Concatenación de cuerdas

8

El reto

Dadas dos cadenas que contienen solo letras minúsculas y sin espacios, el resultado debe ser la cadena más corta, seguida de un guión bajo, seguido de la cadena más larga con la primera instancia de un carácter eliminado para cada carácter que contiene que está en la cadena más corta.

Puede suponer que las cadenas siempre serán de diferentes longitudes.

Casos de prueba:

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)

Reglas

Este es el código de golf, por lo que la respuesta más corta en bytes gana.

Ajay
fuente
2
¿Qué significa " eliminar la primera aparición " cuando la cadena más corta tiene caracteres duplicados?
Peter Taylor
2
Cuatro días es muy corto para elegir un ganador, sugeriría al menos un par de semanas como mínimo. Además, en el futuro sugeriría publicar primero en el Sandbox donde los desafíos se pueden aclarar y mejorar antes de lanzarse.
xnor
3
cadena más pequeña es cadena más corta ... perdón por mi mal inglés
Ajay
66
¿Cuál debería ser la salida juggle juggler? juggle_r(eliminar para cada instancia de personaje) o juggle_gr(eliminar para cada personaje distinto)?
PurkkaKoodari
2
@ Pietu1998 Ese es un buen punto. Deberíamos poner esto en espera hasta que se aclare
Luis Mendo

Respuestas:

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

Descompostura

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
fuente
2

Haskell, 56 55 bytes

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

-1 byte gracias a @xnor

dianne
fuente
Puede cortar un byte atando y\\xpara el 0<1guardia de lo contrario.
xnor
filter(`notElem`x)yes más corto que y\\xcon importación
Damien
@Damien Creo que eso eliminaría todas las ocurrencias de elementos x, no solo las primeras.
dianne
Oh, si tienes razón.
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;}

Probablemente se pueda jugar un poco más simplemente usando matrices sin las listas.

Sin golf y casos de prueba:

Pruébalo aquí

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"));
  }
}

Salida:

sale_inwater
juggle_ostin
juggle_r
Kevin Cruijssen
fuente
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;}

Esto probablemente se pueda jugar un poco más.

Sin golf y casos de prueba

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
fuente
1

Ruby, 65 bytes

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

sin golf

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

61 bytes (en caso de que el argumento sea una matriz de cadenas)

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

Gracias m-chrzan !

cia_rana
fuente
1
gsub!no funciona aquí: se supone que debes eliminar la primera aparición de cada letra. Afortunadamente, sub!que hace exactamente eso, es un byte más corto.
m-chrzan
1
Además, creo que debes nombrar la lambda en este caso, ya que terminas llamándola. Sin embargo, hacer el a,b=b,a if a.size>b.sizeintercambio de cadenas no es recursivo y le ahorra otro byte.
m-chrzan
@ m-chrzan Oh, no observé cuidadosamente la pregunta. ¡Gracias!
cia_rana
61 bytes, ingresados ​​como una matriz de cadenas:->a{a.sort_by!(&:size);a[0].chars.map{|c|a[1].sub!c,""};a*?_}
m-chrzan el
@ m-chrzan ¡Genial! Agregué tu respuesta.
cia_rana
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";

En lugar de $s=preg_replace("#(.*?)".$x."(.*)#","$1$2",$s);usted también puede usarif($z=strstr($s,$x))$s=strstr($s,$x,1).substr($z,1);

Jörg Hülsermann
fuente
0

R, 161 bytes

Esto resultó ser mucho más largo de lo que esperaba, aunque la manipulación de cuerdas suele ser tediosa en R. Creo que esto debería ser fácil de jugar simplemente con otro enfoque.

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="")}

Sin tope

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
fuente
0

Python 2, 81 72 bytes

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

Pruébalo en línea

mbomb007
fuente
2
Creo que puede ahorrar 9 bytes reemplazando las dos primeras líneas cona,b=sorted(input(),key=len)
dianne el
0

Scala, 78 bytes

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

Explicación:

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
fuente