Reto de programacion

EnZo

Parecido al que puso Soy_heaton, trata de manejar cadenas pero un poco mas complejor ami parecer con las reglas que os pongo a continuacion.

Funcionamiento:
Tenemos un texto de muchos caracteres, y queremos mostrar X osea que tendriamos que cortar esa cadena por el X caracter dicho.
La cosa esta en que en vez de cortar una palabra debe dejarlas enteras, no a mitad. Ejem:

"Esta es mi cadena de texto que uso para este ejemplo"

X=2 //Salida: ''
X=4 //Salida: 'Esta'
X=22 //Salida: 'Esta es mi cadena de'

Reglas

  • No se puede usar ninfuna funcion propia del lenguaje, todo desde 0

  • Debe acabar sin espacios al final ni al principio

  • No podemos pasarnos del numero dado, pase lo que pase.

  • El codigo mas corto y elegante deberia ser el mejor.

Lenguajes

  • Los que querais, aunque solo entendere 2 o 3 y no podre ser vuestro juez xD
IS4kO

Veo las reglas un poco ambiguas :)

No se si funciones comodines son lo siguiente, pero bueno ya lo dejo encaminado en esos dos lenguajes:

ASP:

mid(cadena, A, x). Devuelve una subcadena de otra, empezando por A y de longitud x.

trim(cadena). Elimina los espacios iniciales y finales de una cadena.

JAVA:

Y.CharAt(x): pilla caracter x de cadena Y

EnZo

Esos no serian comodines, porque no puedes hacerlo de otra manera.
Sin embargo split creo q era en asp, corta una cadena definiendo el caracter cortante. Eso te serviria para cortar las palabras, y seria una funcion comodin.

Entiendes la diferencia no?

IS4kO

La funcion split lo que te hace es q los caracteres que pilles de una cadena te los mete en una matriz

ejem:

Dim Matriz
Matriz = Split("HOLA ENZO COMO ESTAS", -1, 1)
Matriz (0) contiene "HOLA"
Matriz (1) contiene "ENZO"
Matriz (2) contiene "COMO"
Matriz (3) contiene "ESTAS"

Es decir en cuanto a tipo de función no veo en que se diferencia por ejemplo a trim() y mid()

S

Falso trim y mid y todas las funciones (de cadenas o no) se pueden hacer de otra manera, lo que pasa que esas estan bien programadas y funcionan bien y por eso se toman como estandares.
anda que no puedes recorrer una cadena elemento a elemento y decirle:
IF letra=chr(39) then y cosas a si pero como ya esta trim pos no lo hacemos e = pasa con todas las funciones, es como la encapsulacion en objetos no sabemos como lo hace (ni nos importa en muchos casos) pero sabemos lo que hace.

Por tanto lo de las funciones comodines suena un poco raro tal y como las has definido segun tu definicion todas son comodines ya que todas fijo que se pueden hacer desde cero,eso si yo digo que soy idiota i que no puedo hacerlas desde cero entoces podria utilizarlas? (Todos los caminos llevan a roma solo hace falta concer el mejor y en este caso se decicio que el mejor era trim y las demas funciones por algo estaran el el api de cada lenguaje)

guiye

#5 me lo has quitado de la boca

... ssssssno. XDDD

S

El operador suma es comodín, puedes hacerlo con un ADD xD

IS4kO

creo que yo quería decir lo mismo que #5 no ha ydiferencia entre mid, trim o split, al final todas pueden hacerse por caminos distintos

javithelong

Supongo que sabría, pero eso de las funciones comodin... no se que significa.

¿Es que se pongan todas las funciones que se usen que no sean standard?

:P

A

Más o menos creo haberlo hecho en mirc scripting.

alias cadena {
var %a $2-
var %b $numtok($2-,32)
var %c 1
var %d $1
var %e
while ( %c <= %b ) {
if ( $calc($len(%e) + $len($gettok(%a,%c,32))) <= %d ) { set %e %e $+ $chr(32) $+ $gettok(%a,%c,32) }
else { var %c %b }
inc %c
}
echo %e
unset %e
}

Uso:

/cadena X Y

Donde X es el número de carazteres que queremos devuelva e Y la cadena en si.

Ejemplo:

/cadena 9 Hola esto es una prueba

devuelve: Hola esto

A

Os propongo otro con cadenas.
Un algoritmo que devuelva el porcentaje de letras mayúsculas en una cadena.

Entrada: CADena
Salida: 50%

El algoritmo debe ser lo más sencillo posible y funcionar aunque la cadena contenga símbolos de cualquier tipo.

AvariciA

#include<stdio.h>
#include<string.h>
#define TAM 255

int main(){

char cad[TAM];

int i, cont;

printf("Introduce cadena: ");
gets(cad);
for(i=0;i<strlen(cad);++i){
if(cad>'A'||cad<'Z')
++cont;
}
printf("La media de mayusculas es: %d% de %d caracteres", (cont/i+1)*100, i+1);

return 0;
}

S

#9
Obviamente no soy el mejor expresandolo pero con estandar te queria decir las que ya vienen incluidas en el api. las he llamao estandar por que trim, strstr,substr y otras tantas no solo de cadenas existen en casi todos los lenguajes con un nombre u otro que al final bienen a ser las mismas funciones

PD: strlen seria funcion comodin XD segun lo definido arriba (a calcular la longitud por un for)

dre

lo pasais bien ?

ReMaTxEs

Ahora os propongo yo un pequeño ejemplo (Fue una práctica que me tocó hacer este año en Tecnología de la Programación)

Se trata de realizar un analizador Léxico para un subconjunto del lenguaje de programación PASCAL

El subconjunto lo definías tu (Evidentemente sobre 30 - 40 Tokens) Simplemente había que decir si estaba o no construido de una forma léxica correcta xD

Creo que me ocúpo cerca de las 700 lineas en C xD

A

Yo hice algo parecido a eso. En mi caso se trataba de saber si una frase determinada estaba construída de forma correcta. (gramaticalmente hablando)

Lo de las mayúsculas en mirc scripting con una regex:

alias mayusculas { echo -a $calc($regex($1-,/[A-ZÀ-ÖØ-Ý]/g)/$len($1-)*100)) $+ %
}

EnZo

Bueno parece que la idea no os ha gustado, yo lo hacia porque hay funciones que te acortan muxo trabajo. Y poner un ejercicio de estos para alguien que ha terminado una carrera por ejem es muy muy facil.

Asi que os pediria que lo hicierais sin prohibiciones. Y el fin es hacerlo en las menos lineas posibles con elegancia de sintaxis, y que funcione como se pide.

B

#17

Yo lo que creo es que tu tienes un programa en tu cabeza, y te has puesto a poner reglas sin ton ni son, para que se ajuste y salga lo que tenias en mente.

EnZo

Si, asi es.

De la manera que lo hice me costo pensarlo. Y puse esas normas para que no fuese tan facil y para ver como lo desarrollaban los demas con la idea que yo tenia.

EnZo

$cadena="Mi cadena de texto elegida para el ejemplo";
$maximo=22;
$corto=explode(' ',$cadena);
for ($bucle=0;$bucle<count($corto) && ($suma+strlen($corto[$bucle])-1)<$maximo;++$bucle) {
$suma+=strlen($corto[$bucle])+1;
}
echo trim(substr($cadena,0,$suma));

La forma corta usando las funciones posibles, sin restrinccinoes.

guner

con php, sin singuna funcion propia de php.

<?php

function len($str)
{
&nbsp;&nbsp;&nbsp;&nbsp;$k = 0;
&nbsp;&nbsp;&nbsp;&nbsp;$a = $str[$k];
&nbsp;&nbsp;&nbsp;&nbsp;while (!empty($str[$k]))
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$k++;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;return (int)$k;
}

function quita_($str)
{
&nbsp;&nbsp;&nbsp;&nbsp;$l = len($str) - 1;
&nbsp;&nbsp;&nbsp;&nbsp;$a = 0;
&nbsp;&nbsp;&nbsp;&nbsp;while ($str[$l] == ' ')
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$l--;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$a++;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;$newstr = "";
&nbsp;&nbsp;&nbsp;&nbsp;for ($j = 0; $j <= $l; $j++)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$newstr .= $str[$j];
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;return $newstr;
}

function _quita($str)
{
&nbsp;&nbsp;&nbsp;&nbsp;$k = 0;
&nbsp;&nbsp;&nbsp;&nbsp;while ($str[$k] == ' ')
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$k++;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;$newstr = "";
&nbsp;&nbsp;&nbsp;&nbsp;for ($j = $k; $j <= len($str) - 1; $j++)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$newstr .= $str[$j];
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;return $newstr;
}

function quitaespacios($str)
{
&nbsp;&nbsp;&nbsp;&nbsp;return (quita(quita($str)));
}

function strsub($str, $l)
{
&nbsp;&nbsp;&nbsp;&nbsp;$start = "";
&nbsp;&nbsp;&nbsp;&nbsp;$end = "";
&nbsp;&nbsp;&nbsp;&nbsp;$l--;
&nbsp;&nbsp;&nbsp;&nbsp;for ($i = 0; $i <= $l; $i++)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$start .= $str[$i];
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;for($j = $l + 1; $j <= len($str) - 1; $j++)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$end .= $str[$j];
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;return array($start, $end);
}

function parte($str, $l)
{
&nbsp;&nbsp;&nbsp;&nbsp;$g0 = false;
&nbsp;&nbsp;&nbsp;&nbsp;$matriz = array(0); // [0] => 0;
&nbsp;&nbsp;&nbsp;&nbsp;$str = quitaespacios($str);
&nbsp;&nbsp;&nbsp;&nbsp;if ($l >= len($str))
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$matriz[0] = 1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$matriz[] = $str;
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while ($l < len($str))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$char = $l;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while ($str[$char] != " ")
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($char == 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$g0 = true;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($g0) $char++;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else $char--;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$g0 = false;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$m = strsub($str, $char);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$str = quitaespacios($m[1]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$matriz[0]++;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$matriz[] = quitaespacios($m[0]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$matriz[0]++;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$matriz[] = $str;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;return $matriz;
}

?>

usar así:

parte($cadena, $longitud);
retorna una matriz con este formato:
[0] => Número de divisiones
[1] => división 1
[n]=> División enésima

si encuentra una palabra de más larga que $longitud, partirá la cadena al final de ésta

perdon por las 100 lineas

EnZo

Thank, se nota que te lo has currado mucho. Si lo hubieses hecho con las funciones de PHP no tendria gracia.

Con tu codigo he aprendido que puedes descomponer una cadena de texto sin necesidad de usar funciones extras como puede ser substr. No sabia que actuaba como si fuese un array.

Asi que he rehecho el codigo sin ninguna funcion de PHP todo desde 0.

<?
function len($cadena) {
&nbsp; $i=0;
&nbsp; while ($cadena[$i]!='') {
&nbsp; &nbsp; ++$i;
&nbsp; }
&nbsp; return $i;
}

function sub($cadena,$inicio,$len) {
&nbsp; for ($i=$inicio;$i < ($len+$inicio);++$i) {
&nbsp; &nbsp; $resul.=$cadena[$i];
&nbsp; }
&nbsp; return $resul;
}

function corta($cadena,$maximo) {
&nbsp; $wb=0;
&nbsp; for ($bucle=0;$bucle<len($cadena);++$bucle) {
&nbsp; &nbsp; $letra=sub($cadena,$bucle,1);
&nbsp; &nbsp; if ($letra==' ') ++$wb;
&nbsp; &nbsp; $corto[$wb].=$letra;
&nbsp; }
&nbsp; for ($bucle=0;$bucle < ($wb+1) && ($suma+len($corto[$bucle])-1)<$maximo;++$bucle) {
&nbsp; &nbsp; $suma+=len($corto[$bucle]);
&nbsp; }
&nbsp; return sub($cadena,0,$suma);
}
?>

Utilizacion:

echo corta('Esta es mi cadena de texto',9); //Salida: 'Esta es'

A

Muy bueno el de php.

Abreu

En PHP con $cad y $max:

while($cad[$i]!="" && $i<$max) {
if(!(($i==0 || $i==$max-1) && $cad[$i]==" ") $tmp .= $cad[$i];
$i++;
}
if($cad[$max]!="" && $cad[$max]!=" " && $cad[0]!="") {
$i--;
while($tmp[$i]==" " || $tmp[$i]=="")
$tmp[$i] == "";
$i--;
}
return $tmp;

Creo que ahora va bien.

M

aki va en C:


#include <stdio.h>

void main()
{
char c[]="Esta es mi cadena de texto que uso para este ejemplo";
int p=0, longitud=22, cont=0;

    while(p<longitud)
    {
            if (c[p]==' ')
                    cont++;
            p++;
    }
    p=0;
    while(cont>0)
    {
            printf("%c",c[p]);
            p++;
            if (c[p]==' ')
                    cont--;
    }

}

Basicamente se basa en contar el numero de espacios ke hay antes de rebasar la longitud deseada, y despues sólo se muestran los caracteres ke hay ANTES del n-esimo espacio contado antes. Funciona 100% y más sencillo de entender imposible xD Evidentemente no tiene ningun uso tal como esta, pero lo portas a otro lenguaje siguiendo la idea y usando una funcion y ya esta.

P.D: flipo con algunos poniendo miles de lineas para esta chorrada xDDD

EnZo

Maverick, he probao tu codigo mas que nada por curiosidad que me ha entrado al leer tu PD. Si que funciona, pero no bien, lo he compilao en C cambiando que longitud se meta por teclado, y tmb lo he pasao a PHP, y en ambos me pasa igual.

tu pones esta frase de ejemplo:
'Esta es mi cadena de texto que uso para este ejemplo'

Pues bien si de longitud le pones 4 deberia mostrar 'Esta' no? Pues no lo muestra. Lo muestra si le pones 5 de longitud, xq? porque tu bucle mira hasta que llega un espacio, pero si no llega no, no lo cuenta como palabra.

en php para el que lo quiera comprobar, solo esta traducido.

<?php
$cad='Esta es mi cadena de texto que uso para este ejemplo';
$longitud=4;
$p=0;
$cont=0;

while($p<$longitud) {
&nbsp; if ($cad[$p]==' ') $cont++;
&nbsp; $p++;
}
$p=0;
while($cont>0) {
&nbsp; echo $cad[$p];
&nbsp; $p++;
&nbsp; if ($cad[$p]==' ') $cont--;
}
?>

aLeX

En Java con string tokenizer te lo haces en 3 lineas.

¿Alguien sabe Java?

B

JAVA

String cadena = "Mi cadena de texto", aux = "";
int x = 10;

if (cadena.charAt(x) == " "){

   for (int i = 0; i < x-1; i++){
   aux = axu + cadena.charAt(i);
   
   }

}else{

 while(cadena.charAt(x) != " "){
   for (int i = 0; i < x-2; i++){
   aux = axu + cadena.charAt(i);
   
   }
 x--;
 }

return aux;

pd: no queria utilizar la función subString :P, pero con subString es mas rapido xD

K

En ASM (IDE: RadASM) y enfocado de diferente forma a la que casi todos habéis hecho (A mi parecer más eficiente, pero más liosa) :
http://usuarios.lycos.es/clanics/retomv.zip (Entrar antes en http://usuarios.lycos.es/clanics/, o dará error)

Sorry por no poner comments y por no hacer la parte de eliminar los espacios finales de la string (Los iniciales sí los borra), pero llevo prisa. Si eso lo hago esta noche.

No uso ningún opcode de tratamiento de cadenas, para sumarle dificultad xD

guner

tras ver algunos comentarios, explico el por qué de mis 100 líneas de código.

enzo nos retara a que no usaramos funciones propias del lenguaje para el tratamiento de cadenas, lo único que hice fue emularlas, para hacer el algoritmo tal y como se haria con esas funciones, desde luego, no es necesario, además mi función no hace exactamente lo que pedia el problema ... me enrollé.

Tal y como yo lo haría. (lenguaje: pseudocódigo español)

int longitud;
string cadena;
string devcadena = "";
int ultimoespacio=0;
entero j=0;

mientras (j < longitud Y)
j++;
si (cadena[j] == ' ') entonces ultimoespacio = j;
fin while
para (i=0 hasta i <= ultimoespacio-1 haz i+1)
devcadena += (añade) cadena;
fin para

retorna devcadena

Usuarios habituales