Concatenação de String

8

O desafio

Dadas duas cadeias contendo apenas letras minúsculas e sem espaços, o resultado deve ser a cadeia mais curta, seguida por um sublinhado, seguida pela cadeia mais longa com a primeira instância de um caractere removido para cada caractere contido na cadeia mais curta.

Você pode assumir que as strings sempre terão comprimentos diferentes.

Casos de teste:

sale
salinewater
Result: sale_inwater (only the first 'a' in salinewater is removed)

jostling
juggle
Result: juggle_ostin (juggle is the shorter string)

juggle
juggler
Result: juggle_r (a 'g' is removed for every 'g' in the shorter string)

Regras

Isso é código-golfe, então a resposta mais curta em bytes vence!

Ajay
fonte
2
O que significa " remover a primeira ocorrência " quando a cadeia mais curta possui caracteres duplicados?
Peter Taylor
2
Quatro dias é muito curto para escolher um vencedor, sugiro pelo menos duas semanas no mínimo. Além disso, no futuro, sugiro primeiro postar no Sandbox, onde os desafios podem ser esclarecidos e aprimorados antes de serem lançados.
Xnor
3
corda menor é mais curto corda ...... desculpe pelo meu mau Inglês
Ajay
6
Qual deve ser a saída juggle juggler? juggle_r(remover para cada instância de caractere) ou juggle_gr(remover para cada caractere distinto)?
PurkkaKoodari
2
@ Pietu1998 Esse é um bom ponto. Devemos colocar isso em espera até esclarecer #
Luis Mendo

Respostas:

3

JavaScript (ES6), 78 75 69 bytes

const 
     g=(x,y)=>x[y.length]?g(y,x):[...x].map(c=>y=y.replace(c,''))&&x+'_'+y
;

console.log(g.toString().length + 2);   // 69
console.log(g('sale', 'salinewater'))   // sale_inwater
console.log(g('juggle', 'juggler'))     // juggle_r
console.log(g('jostling','juggle'))     // juggle_ostin

Demolir

x[y.length]?g(y,x):        \\ Make sure that x is the shorter string
[...x]                     \\ Spread string in array of characters
.map(c=>y=y.replace(c,'')) \\ For each character remove its first occurence in y
&&x+'_'+y                  \\ Concat x and changed y 
Lmis
fonte
2

Haskell, 56 55 bytes

import Data.List
x%y|(0<$y)<(0<$x)=y%x|z<-y\\x=x++'_':z

-1 byte graças a @xnor

dianne
fonte
Você pode cortar um byte vinculando y\\x-o à 0<1outra proteção.
Xnor
filter(`notElem`x)yé menor do que y\\xcom importação
Damien
@ Damien Eu acho que iria remover todas as ocorrências de elementos de x, não apenas os primeiros.
dianne
Oh, sim, você está certo.
Damien
1

Java 7, 262 bytes

import java.util.*;String c(String z,String y){int i=0,l=y.length();if(z.length()>l)return c(y,z);List x=new ArrayList();for(;i<l;x.add(y.toCharArray()[i++]));for(Object q:z.toCharArray())x.remove(q);String r="";for(i=0;i<x.size();r+=x.get(i++));return z+"_"+r;}

Provavelmente pode ser jogado mais usando apenas matrizes sem as listas.

Casos não testados e de teste:

Experimente aqui.

import java.util.*;
class M{
  static String c(String z, String y){
    int i = 0,
        l = y.length();
    if(z.length() > l){
      return c(y, z);
    }
    List x = new ArrayList();
    for(; i < l; x.add(y.toCharArray()[i++]));
    for(Object q : z.toCharArray()){
      x.remove(q);
    }
    String r = "";
    for(i = 0; i < (x.size()); r += x.get(i++));
    return z+"_"+r;
  }

  public static void main(String[] a){
    System.out.println(c("sale", "salinewater"));
    System.out.println(c("jostling", "juggle"));
    System.out.println(c("juggle", "juggler"));
  }
}

Resultado:

sale_inwater
juggle_ostin
juggle_r
Kevin Cruijssen
fonte
1

Java 8, 156 bytes

String a(String x,String y){int l=x.length(),m=y.length();String b=l>m?x:y,s=m<l?y:x;for(char c:s.toCharArray()){b=b.replaceFirst(""+c,"");}return s+"_"+b;}

Provavelmente isso pode ser jogado um pouco mais.

Casos não testados e de teste

interface A {
    static String a(String x,String y){
        int l=x.length(),m=y.length();
        String b=l>m?x:y,s=m<l?y:x;
        for(char c:s.toCharArray()){
            b=b.replaceFirst(""+c,"");
        }
        return s+"_"+b;
    }

    static void main(String[]a) {
        System.out.println(a("sale","salinewater"));
        System.out.println(a("jostling","juggle"));
        System.out.println(a("juggle","juggler"));
    }
}
mrco
fonte
1

Ruby, 65 bytes

->a,b{a,b=b,a if a.size>b.size;a.chars.map{|e|b.sub!e,""};a+?_+b}

destroçado

->a, b{
  a, b = b, a if a.size > b.size
  a.chars.map { |e|
    b.sub! e, ""
  }
  a + ?_ + b
}

61 bytes (caso o argumento seja uma matriz de cadeias)

->a{a.sort_by!(&:size);a[0].chars.map{|c|a[1].sub!c,""};a*?_‌​}

Obrigado, m-chrzan !

cia_rana
fonte
1
gsub!não funciona aqui - você deve remover a primeira ocorrência de cada letra. Felizmente, o sub!que faz exatamente isso, é um byte mais curto.
M-chrzan 23/09/16
1
Além disso, acho que você precisa nomear o lambda nesse caso, pois acaba chamando-o. No entanto, fazer a,b=b,a if a.size>b.sizea troca das seqüências não é recursivo e economiza outro byte.
M-chrzan 23/09/16
@ m-chrzan Oh, eu não observei cuidadosamente a pergunta. Obrigado!
cia_rana 23/09/16
61 bytes de entrada como, uma matriz de cadeias:->a{a.sort_by!(&:size);a[0].chars.map{|c|a[1].sub!c,""};a*?_}
m-Chrzan
@ m-chrzan Ótimo! Eu adicionei sua resposta.
Cia_rana 23/09/16
0

PHP, 154 bytes

list($f,$s)=strlen($b=$argv[2])<strlen($a=$argv[1])?[$b,$a]:[$a,$b];foreach(str_split($f)as$x)$s=preg_replace("#(.*?)".$x."(.*)#","$1$2",$s);echo$f."_$s";

Em vez de $s=preg_replace("#(.*?)".$x."(.*)#","$1$2",$s);você também pode usarif($z=strstr($s,$x))$s=strstr($s,$x,1).substr($z,1);

Jörg Hülsermann
fonte
0

R, 161 bytes

Isso acabou sendo muito mais longo do que eu esperava, embora a manipulação de cordas seja geralmente entediante em R. Eu sinto que isso deve ser facilmente jogável com o uso de outra abordagem.

function(x,y){s=strsplit;if(nchar(x)>nchar(y)){v=y;w=x}else{v=x;w=y};v=s(v,"")[[1]];w=s(w,"")[[1]];j=0;for(i in v){j=j+1;if(i==w[j])w[j]=""};cat(v,"_",w,sep="")}

Ungofled

function(x,y){
    s=strsplit                      # alias for stringsplit
    if(nchar(x)>nchar(y)){v=y;w=x}  # assign v/w for the short/long strings
    else{v=x;w=y}
    v=s(v,"")[[1]]                  # split short string into vector
    w=s(w,"")[[1]]                  # split long string into vector
    j=0
    for(i in v){                    # for each char in short string, check
        j=j+1                       # if is equal to corresponding char in
        if(i==w[j])w[j]=""          # long, replace long with "" if true
    }
    cat(v,"_",w,sep="")             # insert _ and print
}
Billywob
fonte
0

Python 2, 81 72 bytes

a,b=sorted(input(),key=len)
for c in a:b=b.replace(c,"",1)
print a+"_"+b

Experimente online

mbomb007
fonte
2
Eu acho que você pode economizar 9 bytes, substituindo as duas primeiras linhas coma,b=sorted(input(),key=len)
Dianne
0

Scala, 78 bytes

def f(a:String,b:String):String={if(a.size>b.size)f(b,a)else
a+"_"+(b diff a)}

Explicação:

def f(a:String,b:String):String={ //define a method f which has two String parameters and returns a String
                                  //(because it's recursive, scala can't figure out the return type)
  if (a.size > b.size)            //make sure that a is the shorter string
    f(b, a)
  else
    a+"_"+(b diff a)              //`b diff a` removes all elements/chars of a from b
}
corvus_192
fonte