Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Obtener un dígito en una posición (https://www.clubdelphi.com/foros/showthread.php?t=90775)

andrecuellar 01-09-2016 21:35:25

Obtener un dígito en una posición
 
Buenas, ya voy aproximadamente un año con delphi y le entiendo perfectamente bien, pero me dejaron un problema que la verdad hasta ahora me ha dejado mal parado, no puedo hacerlo y da para pensar, me han puesto una condición (sin usar for, while, repeat y todo lo que viene a ser ciclo repetitivo), el problema es el siguiente:

Escribir el código de un programa en delphi en modo consola que pida dos números N y K donde se muestre el dígito que se encuentre en la posición K del número N ( Sin usar ciclos repetitivos )

ejemplo:
N:= 1248935
K:= 4
result:= 8

El problema este me pone pensativo cuando me pidieron no usar while, ni for, ni repeat, alguien tiene alguna solución o aporte que pueda servir? Uso tanto los ciclos que no se me ocurre como hacerlo sin ellos. Por favor. Gracias de antemano :)

Quizás podría solucionarse con una fórmula que se usa para contar el número de dígitos, que la verdad nunca se me habría ocurrido
Código Delphi [-]
digitos:= trunc(Ln(N)/Ln(10))+1;

Casimiro Notevi 01-09-2016 21:46:45

Recuerda poner títulos descriptivos a tus preguntas, gracias.

andrecuellar 01-09-2016 21:48:38

Cita:

Empezado por Casimiro Notevi (Mensaje 508373)
Recuerda poner títulos descriptivos a tus preguntas, gracias.

Editado, gracias :)

JOSEPE 01-09-2016 21:51:06

Pues eso es lo que tienes que hacer, usar logaritmos y exponenciales sobre base 10. Realmente no es dificil.

Otra forma un poco "chueca" que creo no es la idea, es pasar el numero a string, y de ahi hacer referencia al caracter apropiado.

ecfisa 01-09-2016 22:16:42

Hola andrecuellar.

¿ Ya revisaste los enlaces que hay al pié de esta página ?

Saludos :)

andrecuellar 01-09-2016 22:21:45

Cita:

Empezado por ecfisa (Mensaje 508376)
Hola andrecuellar.

¿ Ya revisaste los enlaces que hay al pié de esta página ?

Saludos :)

no lo había visto, pero las soluciones que dan son con manejo de cadenas (no es con manejo de cadenas tampoco que se debe hacer), o también se las dan con ciclos repetitivos, que si pudiera usarlos entonces ya lo habría hecho, de todas maneras gracias :)

ecfisa 02-09-2016 06:18:05

Hola.

Fijate si te sirve de este modo:
Código Delphi [-]
function DigitAtPos(Number: LongInt; Position: Byte): Integer;
var
  len: Integer;
begin
  Number := Abs(Number);
  len    := Trunc(ln(Number)/ln(10))+1;
  if (Number = 0) or (Position <= 0) or (Position > len) then
    Result := -1
  else
  begin
    Position := len - Position + 1;
    Result   := Number div Trunc(Exp(Ln(10)*(Position-1))) mod 10;
  end;
end;

Uso:
Código Delphi [-]
...
  Writeln(DigitAtPos(-1248935, 6)); //  -> 3

Saludos :)

roman 02-09-2016 16:21:03

Dos soluciones no iterativas:

1. Variante de la de ecfisa:

Código Delphi [-]
function DigitAtPos(N: LongInt; K: Byte): Integer;
begin
  Result := (N div Trunc(IntPower(10, K))) mod 10;
end;

2. Versión recursiva

Código Delphi [-]
function DigitAtPosR(N: LongInt; K: Byte): Integer;
begin
  if K = 0 then
    Result := N mod 10
  else
    Result := DigitAtPosR(N div 10, K - 1);
end;

En ambos casos, los dígitos se cuentan desde el 0 de derecha a izquierda.

LineComment Saludos

andrecuellar 06-09-2016 23:15:09

Gracias a todos!
 
Gracias a todos! al final terminé usando esto que igual me sirvió :D
Lo voy a poner todo en uno en consola para no estar separando todo en funciones

Código Delphi [-]
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;
var N, D, NumDigits, r, valordig: integer; K: byte;
begin
readln(N);
readln(k);
 NumDigits:= trunc(Ln(N)/Ln(10))+1;
 D:= trunc(exp((NumDigits-k)*Ln(10)));
 r:= n div D;
 r:= r mod 10;
Writeln('El valor del digito es: ',r);
readln;
end.

Muchas gracias a todos los que me ayudaron, simplemente tenía que usar la "fórmula" para obtener el número de dígitos y luego usar otra. Gracias!

Tema resuelto :)

BDWONG 07-09-2016 05:00:10

Hola si en tu caso todo es valido excepto los ciclos repetitivos puedes probar tambien con esta alternativa

Código Delphi [-]
function DigitAtPos(N: DWord;K:Byte): Dword;
begin
 Result:=0;
 if (N>=K) and (K>0) then
    Result:=ord(IntToStr(N)[k])-$30;
end;


begin
   WriteLn(DigitAtPos(1248935,4));
   ReadLn;
end.

SALUDOS:D

AgustinOrtu 07-09-2016 06:33:57

Cita:

Empezado por BDWONG (Mensaje 508573)
Código Delphi [-]
function DigitAtPos(N: DWord;K:Byte): Dword;
begin
 Result:=0;
 if (N>=K) and (K>0) then
    Result:=ord(IntToStr(N)[k])-$30;
end;

begin
   WriteLn(DigitAtPos(1248935,4));
   ReadLn;
end.

Ese codigo lo veo y no entiendo nada :( es como si estuviese cifrado.. es peor que leer C :D

Fuera de bromas, realmente no lo entiendo, en donde esta el "truco"? :confused:

roman 07-09-2016 16:04:46

Cita:

Empezado por AgustinOrtu (Mensaje 508574)
Fuera de bromas, realmente no lo entiendo, en donde esta el "truco"? :confused:

Convierte el número en una cadena, toma el k-ésimo caracter y lo devuelve restándole $30 que es el código ascii del 0, es decir, conviertiendo el caracter de vuelta en número.

De todas formas, ya en el mensaje #6 se había establecido que no podían usarse cadenas.

LineComment Saludos

AgustinOrtu 07-09-2016 18:34:39

Cita:

Empezado por roman (Mensaje 508576)
Convierte el número en una cadena, toma el k-ésimo caracter y lo devuelve restándole $30 que es el código ascii del 0, es decir, conviertiendo el caracter de vuelta en número

Gracias por explicarlo roman, la verdad no conocia ese "truquito" jugando con la tabla de ASCII. O bueno, en realidad lo mas preciso es decir que no lo recordaba, eso creo que lo vi alguna vez cuando nos enseñaban assembler :)

roman 07-09-2016 18:55:40

Quizá sería más claro restarle Ord('0') en lugar de $30 ;)

LineComment Saludos

BDWONG 07-09-2016 19:17:09

Joder no había visto el mensaje 6 lo siento, AgustinOrtu no creo que sea tan criptico el código he visto peores :eek:
Saludos...

BDWONG 07-09-2016 19:56:20

Pequeña variante de román cuenta los dígitos de izquierda a derecha

Código Delphi [-]
function DigitAtPos(N,K: Dword): DWord;
var e: DWord;
begin
   Result:=0;
   e:=(trunc(Ln(N)/Ln(10))+1);

   if K<=e then Result:=(N div trunc(intpower(10,e-K)))mod 10;
end;

begin
  Writeln(DigitAtPos(1248935,4));
  ReadLn;
end.

ecfisa 07-09-2016 21:09:25

Hola.

Una observación sobre alguna de las variantes expuestas. Dado que realizan un conteo de base 0 (0, 1, 2, ...) la función debería devolver un valor distinto a 0 para señalizar un resultado inválido.

Saludos :)


La franja horaria es GMT +2. Ahora son las 20:46:04.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi