Ejercicio (como) para volverse loco
Resolviendo una pregunta en otro lado llegue después de un par de iteraciones a una solución bastante extraña para resolver el siguiente problema:
"Crear un método que reemplace todas las letras L
encontradas en HELLO WORLD
con una x
y que la x
aparezca incrementada en cada ocurrencia de L
"
Ejemplos:
Salida: "HExxxO WORxxxD"
Salida: "HExxxO xxxAZY xxxxIMBO WOxxxxxR"
Restricciones: Únicamente se pueden utilizar los siguiente métodos de la clase String:.length; .indexOf; y.substring();
y claro el resto del lenguaje ( for, while, operador + variables etc. ). Ninguna otra clase, ningún otro método.
Mi solución solo dos sentencias:
Pff... para volverse loco.
Ahi se los dejo de tarea.
Update Le había puesto que regresaba XXX en unos y xxx en otros. Es siempre con la misma "x" ( cualquiera de las dos )
Mi error, corregido. Gracias wishmaster77 por notarlo.
EDIT: (ezamudio) Si piensan resolver el ejercicio, no vean todavía los comentarios, porque ya hay algunas soluciones ahí; primero resuélvanlo y luego ponen su solución en los comentarios, para compararla con las que ya están...
- Inicie sesión o regístrese para enviar comentarios
Chale
Encontré una solución pero en 3 sentencias (1 declaración, 1 condición de ciclo, y la transformación), y sin length()...
A menos que el ciclo y la transformación se cuenten como una sola sentencia, pero pues es un ciclo con un bloque de una sola sentencia, yo los contaría como dos...
Jajaj también estas bien 'che
Jajaj también estas bien 'che loco mano...
Si, es sin length y estás a un pasitito de transformar de 3 en 2 :)
Por cierto luego encontré uno en una sola sentencia, pero ya está muy fumada ( aunque no tanto si lo tuyo lo tuyo , es programar en lisp )
ajajaj
aaaaah ya sé!!!!
Con for en vez de while, metes la declaración al for y queda en 2. Ya lo tengo. Ahora pensaré en ese de una sentencia... con recursión seguramente...
Recursiva
(si ya sé que yo mismo estuve jodiendo con que es "recurrente" pero entre devs decimos muchos pochismos)
Con recursión se puede hacer en una sola línea, pero hay que hacer la función de dos parámetros: la cadena a transformar y la cadena de reemplazo para la L. Y pues queda un poquito más flexible porque entonces puedes reemplazar la L con alguna otra cosa (de un solo caracter).
Esperaré unas horas más a ver si alguien más se anima, pero si sigue igual de popular este post para las 2pm ya publico mis soluciones.
Pos claaaaro... jejejej el
Pos claaaaro... jejejej el for tiene tres partes el while una nomás :) -> 1 sentencia.
Xacto la otra es la versión recursiva. Pero en Java se ve como perl :S
conditional statement
Las sentencias condicionales cuentan como una sola, no? porque pues tienen que tener tres partes a fuerzas... o cuentan como 2? o como 3? porque mi versión recursiva de una línea es con una sentencia condicional.
Mi resultado
Me estorba esa declaracion de String x, estoy viendo si la puedo desaparecer:
for (int contador = 0, posicion = 0;(posicion = in.indexOf ("L")) > -1;contador ++) {
String x = "";
for (int i = 0; i <= contador; i++) {x += "x";}
in = in.substring (0, posicion) + x + in.substring (posicion + 1, in.length ());
}
return in;
}
Cuentan como 1... una
Cuentan como 1... una sentencia aun cuando tenga ternarios anidados.
recursividad?
Me late que va orientado mas a la recursividad, aun asi no puedo sacarlo en dos lineas, esta bueno esto!
Mi solución
yo no estoy tan loco me quedo asi:
String tem,salida="";
int contador=1;;
for(int i=0; i<in.length();i++){
tem=in.substring(i, i+1);
if(tem.equals("l"))
{
for(int j=0;j<contador;j++){
salida += "x";
}
contador++;
}else{
salida = salida +tem;
}
}
return salida;
}
soluciones
bueno bueno lo que me agrade de la programación es que puedes tener diferentes soluciones a un mimo problema, y habia pensado en un while y una sentencia... no lo había pensado en algo recurrente....
Recurrente?
Puagh.. prefiero oir "recursivo" aunuque no existe ( ya ves lo que provocas enrique? ) jajajaj </broma>
De hecho no hay taaantas opciones, todas son el mismo algoritmo ( al menos los que he visto ) solo que implementado de forma diferente.
En mis propias palabras
1.- Comparar cada caracter
2.- Si coincide reemplazar con x
3.- Incrementar las x's
4.- Repetir.
Weno creo que si me ví demasiado abstracto.
My recursiva ( no quería hacerla, por que me daba flojera ) es de 1 sentencia con 3 ternarios anidados.
3 ternarios?
No manches es demasiado! yo hice una recursiva con solamente 1 ternario! pero la función requiere 2 parámetros...
¿Debe ser así? Entrada:
¿Debe ser así?
Entrada: "HELLO WORLD"
Salida: "HEXXXO WORXXXD"
Entrada: "HELLO LAZY LIMBO WORLD"
Salida: "HExxxO xxxAZY xxxxIMBO WOxxxxxR"
¿O así?
Entrada: "HELLO WORLD"
Salida: "HEXXXO WORXXXD"
Entrada: "HELLO LAZY LIMBO WORLD"
Salida: "HEXXXO XXXAZY XXXXIMBO WORXXXXXD"
*EDIT: No @Oscar, osea ve el órden en "Hello lazy limbo world" tú pones "Hexxxo xxxazy xxxximbo woxxxxxr" y yo sugerí: "Hexxxo xxxazy xxxximbo worxxxxxd"
wishmaster77 My bad... es
wishmaster77 My bad... es con uno o co el otro.. me equivoque.
Fixing...
Sepa... no tendrás un
Sepa... no tendrás un ternario mezclado con algún loop ? jejeje .. Propongo que lo veamos el lunes, hay quién le da ganas de hacer eso el finde...
ok!...entonces ya me quedó,
ok!...entonces ya me quedó, pero en 2 for un if, una declaración, un incremento y una asignación.
PERO es capaz de hacerlo con cualquier letra, no sólo la L jejejeje. ¿Se puede postear el resultado?
Postealo
Esa es la idea, empezar a ver las soluciones que han hecho los miembros de la comunidad.
Wiii
Jajaja si me salio.
Tal vez no es lo mas eficiente, ni lo mas estetico pero me salio jajajajaja
String resultado = "";
int tamaño = entrada.length();
int inicio = 0;
int nx = 1;
String temporal = entrada;
while(temporal.indexOf("L")!=-1){
resultado = resultado + temporal.substring(0,temporal.indexOf("L"));
for(int a = 0; a<nx; a++){
resultado = resultado + "x";
}
nx++;
inicio = temporal.indexOf("L")+1;
tamaño = temporal.length();
temporal = temporal.substring(inicio,tamaño);
}if(temporal.length()!=0){
resultado +=temporal;
}
return resultado;
}
creo que respete las restricciones jajajaja ¿no?
Seria bueno
Ojala que se denla respuesta el lunes, yo quiero intentar hacer el ejercicio pero estoy algo saturado del trabajo. Sirve que también entran algunos tantos el fin de semana y se publican mas respuestas.
Saludos.
Entendido:
Entendido: http://pastebin.com/eD0HcNWE
Revisenlo pues =)
:( si se pa locos
public static void main(String[] args) {
System.out.println(replace("hello world", "x"));
}
public static String replace(String in, String xs) {
int lPosition = in.indexOf("l");
if (lPosition != -1) {
in = in.substring(0, lPosition) + xs + in.substring(lPosition + 1);
xs += xs;
in = replace(in, xs);
}
return in;
}
}
UPDATE: Chin por las prisas un ERROR jejeje, est es el bueno
public static void main(String[] args) {
System.out.println(replace("hello world", "x"));
}
public static String replace(String in, String xs) {
if (in.indexOf("l") != -1) {
in = in.substring(0, in.indexOf("l")) + xs + in.substring(in.indexOf("l") + 1);
xs = xs + "x";
in = replace(in, xs);
}
return in;
}
}
verborrea
Ya veo por qué nos tiran tanto a los javeros con que somos unos choreros y que en Java hay que escribir mucho código... interesante ver las soluciones que han publicado hasta ahora pero ninguna ha tenido menos de 4 líneas! Las más compactas hasta ahorita son la de java.daba.doo y la de rodrigo salado...
mmmm pues sin comentarios... jejeje
Pues que les digo esto esta muy YUPY jejeje....
return in.indexOf("l") != -1 ? replace(in.substring(0, in.indexOf("l")) + xs + in.substring(in.indexOf("l") + 1), xs + "x") : "";
}
UPDATE: Lo que no me latio es que tenga un "x" hardcoreada... -1 por eso :P
Mi solución
Aquí está mi solución. Para los que no la quieran ver, pues no la pueden ver y ya. Para los que la quieran ver, arrastren el mouse sobre el área donde parece que no hay nada para que vean el texto.
Y la versión de una sola línea:
No es lo más entendible del mundo, pero pues me obsesioné un poco con lo que decía Oscar de que le había salido en dos líneas.
la probaste?
Rodrigo, probaste tu función? porque según yo devuelve la cadena incompleta (por el último return de cadena vacía)
@OscarRyz, @ezamudio.
si pudieran programarías con el efecto mariposa, LOL jejeje, en una ocasión me mostraron esa caricatura y era algo con editores ... regresando al tema, si le metemos un "l" al mio y creo que a varios más se truena gachisimo la memoria, esto es justo para el un tema que saco Oscar... por ejemplo
public static void main(String[] args) {
System.out.println(replace2("hello world", "l"));
}
public static String replace2(String in, String xs) {
return in.indexOf("l") != -1 ? replace(in.substring(0, in.indexOf("l")) + xs + in.substring(in.indexOf("l") + 1), xs + "x") : in;
}
}
/*
run:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Arrays.java:3209)
at java.lang.String.<init>(String.java:215)
at java.lang.StringBuilder.toString(StringBuilder.java:430)
at orscarchalanger.Main.replace(Main.java:19)
*/
UPDATE: Lo siento chicos, gracias Chochos, me falto el 'in' al final, no le digas a @citADN, si no me va a regaña por no estar trabajando jejejeje
@
ohhhhh
sorprendido por la solución de ezamudio.... el for era algo que había pensado pero pensé que su estructura era rigida y que solo podias poner algún valor numérico o alguna referencia d este tipo pero no imagine que pudiera aceptar algo diferente como un string
claro
Si tratas de reemplazar la L con otra L pues nunca va a terminar, y la versión recursiva va a acabarse el stack hasta tronar como Jenga. La única manera de arreglar eso es validar que tu xs no sea L, tal vez arrojar una IllegalArgumentException en ese caso.
Y cómo está eso de programar con el efecto mariposa? Digo, lo conozco (explicación sencilla de teoría del caos) pero aplicado a programación?
un solo ternario
Oscar, ya viste que sí se puede en una sola línea con un solo ternario?
Lo del efecto mariposa me
Lo del efecto mariposa me parece que fue una "re-interpretación" de Rodrigo.
jejeje
Quizá se refiere a que los verdaderos programadores utilizan mariposas para programar ( no nano, ni emacs, ni vi, ni siquiera, ed o cat )
http://xkcd.com/378
Viendo la solución creo que hice demasiadas validaciones en mi version recursiva.
La del for,no necesita cuerpo ( solo un ";" )
Por cierto, si se usa
indexOf( char c, int from )
se evita reescanear toda la entrada de nuevo.Me voy a dar otro chance para mi versión recursiva :)
Chau!
Sobre el ternario: Si me dí vuelo validando condiciones innecesarias
Ahi pa'lunes
Una línea
Ah entonces ya sé cómo podemos hacerlo de una sola línea, iterativo. Mezcla de tu solución con la mía, Oscar:
De hecho cuando empecé a hacerlo tenía un while, la inicialización de "x" y en el cuerpo la concatenaba como está aquí. Pero luego la pasé al for, y quedó la solución que puse originalmente. Pero esta me gusta más, está como para entrevista, presentar esa línea y que te digan qué hace...
Sé que usar la variante de indexOf con posición inicial evita escanear toda la entrada, pero vamos, no estábamos compitiendo por desempeño sino por menos líneas, no? Al menos eso entendí al principio... como segunda parte está bueno pensarlo en performance y también en uso de memoria (concatenar es muy ineficiente)
Al fin 2 lineas: public
Al fin 2 lineas:
if(cadena.indexOf(letra) != -1)
cadena =
cadena.substring(0, cadena.indexOf(letra)) +
reemplazo +
reemplazar(
cadena.substring(cadena.indexOf(letra) + 1),
letra,
reemplazo+reemplazo.substring(0,1)
);
return cadena;
}
Ya ahí estan las 2 =) recursiva e iterativa: http://pastebin.com/wsKsdibz
wishmaster
Si usas operador ternario, puedes convertir tu función a una sola linea.
mmm...veamos
mmm...veamos
Ahora si ya completo, gracias
Ahora si ya completo, gracias a @Ezamudio por la idea del ternario, y pues ahora si tengo mis 3 implementaciones. http://pastebin.com/cXDJbDkR
@ezamudio... a chirriones
Hice un copy&paste de tus respuestas, y no hicieron nada :P. Soy yo?
La onda creo que es que nunca se le asigna nada modificado a 'in'...
rodrigo
Las probé todas, no iba a subir código sin compilar y probar... mis versiones ni siquiera dicen
in
, la variable ess
... no imprimen nada, hay que llamarlas imprimir el valor de retorno@ezamudio. Va
Sí ezamudio, los voy a probar bien vale...
Están muy chidos ya los corrí, fue un error de teclaso :P
Mi propuesta
{
if (in.indexOf('L') > -1)
in = in.substring(0, in.indexOf('L')) + r + replace(in.substring(in.indexOf('L') + 1), r + "X");
return in;
}
Tuve que aumentar un parámetro, ustedes cuenten cuantas líneas son la primera llamada sería
replace(hw, "X")
PD: Que conste que vi las otras soluciones despues de postear la mia
Para el Chochos: Hago constar que la revisión de las soluciones previas fué posterior a la publicación de la propia
Julia
Para ti aplica lo mismo que para wishmaster: si cambias tu
if
por operador ternario, te queda de una línea.Si no quieren hardcodear* la X, pueden poner
r + r.charAt(0)
.Ya al final en términos de tamaño, me gusta más la versión iterativa que es amalgama de lo que puso Oscar con lo que había puesto yo. Un for sin cuerpo, que pues se debe considerar una sola sentencia...
* palabra reservada de Español++
jajaja en ves de que Rodrigo
@jvidales jajaja en ves de que Rodrigo se fuera a trabajar te trajo acá ... jajaja ta vaciado eso.
Que conste, que no se trata de líneas, sino de "sentencias" ( o statements )
Pues un statement como el for puede partirse en tres líneas.
Pues bien, que bueno que les parecio interesante el reto. La verdad es que cuando iniciamos parece casi imposible, pero así son muchas cosas, una vez realizadas no lo parecen tanto.
Aquí está el post original ( voten por mi respuesta :P ) Replacing a character every ocurrence in a string in Java Como podrán ver, solo dos personas lo pusimos en tan pocas sentencias, y quizá si aquí no hubiera llegado diciendo "en 2!!!" hubiera pasado algo similar.
p.d. No se puede usar
charAt
no está en la lista de métodos permitidos.Chau!
charAt
Cierto, no se puede usar charAt. Bueno entonces
x.substring(0,1)
, ese sí se puedeRe: Julia
Pues si, ya dejé la versión completa de la clase en pastebin (de la primer versión hasta la recursiva con ternario).
jaja chale
Al parecer solo yo me la crei que era con un solo parametro jeje.
Pues lo que hize fue algo horroso, lo que se trata de evitar en java (por eso es verboso, algo que agradezco), pero en fin, esta es mi solución sin ser recursiva
public static void main(String[] args){
System.out.println("HELLO WORLD => " + replace("HELLO WORLD"));
System.out.println("HELLO LAZY LIMBO WORLD => " + replace("HELLO LAZY LIMBO WORLD"));
}
public static String replace(String str){
for(String i="1", tmp="";
str.indexOf('L') > -1
&& ((tmp = str.substring(0, str.indexOf('L'))) != null)
&& ((str = str.substring(str.indexOf('L')+1, str.length())) != null);
str = tmp + str + ((i = Integer.toString(Integer.parseInt(i)+1)).substring(0, 0)) ){
for(int j=0; j<Integer.parseInt(i); j++){tmp = tmp + "x"; }
}
return str;
}
}
Es interesante observar como cada uno piensa de manera muy distinta.
Sobres
parámetros
yo también hice mi función de un solo parámetro. La iterativa, al menos. La recursiva requiere un segundo parámetro.
Esta de Nopalin creo que es la más enredada que he visto, pero ilustra un punto no muy conocido: en un
for
se pueden inicializar varias variables del mismo tipo.Wow, genial @ezamudio!
Sorprendente los códigos de Enrique. Me gusto el del for sin cuerpo mas que el "recursivo" tiene mas estilo (para mi)
for sin cuerpo
Gracias; ese último ya fue mezcla de lo que hizo Oscar con mi for original. Quería hacer un for con 2 inicializadores: uno para el contador y otro para las X, pero solamente se pueden inicializar variables del mismo tipo (es una sola declaración a fin de cuentas). Nopalin hizo algo así pero tuvo que hacer el indicador de posición como cadena. Tal vez se pueda integrar eso a una sola línea, pero a fin de cuentas creo que el costo de estar convirtiendo el indicador de posición entre String y entero para cada L encontrada, será mayor que el costo de escanear completa la cadena desde el inicio buscando una nueva L.
Segunda ronda
Ahora podrían hacer la función pero en vez de enfocarse a menos sentencias, enfocarse a dos cosas (pueden tirarle a una, a la otra, o a una combinación de ambas):
1. Velocidad
2. Uso de memoria (o sea, que use la menor memoria posible).
Las variantes que hemos puesto, tanto iterativas como recursivas, de una o dos líneas, honestamente no son óptimas ni en uso de CPU ni en uso de memoria. Estuvo muy interesante porque se trataba de aprovechar al máximo el conocimiento del lenguaje y de algoritmos en general, para realizar el algoritmo de la forma más compacta posible en cuanto a código, pero nada más...
Otra variante: usando expresiones regulares...
según
pues segun lo que recuerdo de mi clases de analisis de algoritmos decian que los algoritmos que recurrentes son los que tienes una función asociada de nlogn o logn imagino que esto sera para la velocidad, para uso de la memoria pues lo veo un poco complicado porque tendrias o se tendria que definir el entorno ademas con las diferencias de equipo no es lo mismo usas 4 mb de memoria, en equipo que tienes ddr3 1600 a un equipo con memorias ddr2 433 vamos que tiene y va a existir una diferencia.....minima pero existe......