Probar si se le da un número si es un número Keith

14

Dado que los números y secuencias de Fibonacci parecen ser un tema popular para el golf de código, pensé que podría ser un desafío divertido codificar el golf con números de Keith .

Por lo tanto, propongo un desafío que consiste en crear una función que tome un número entero y devuelva un verdadero o falso dependiendo de si el número es un número Keith o no.

Más sobre los números de Keith

En matemáticas recreativas, un número de Keith o número de réfigit (abreviatura de dígito repetitivo similar a Fibonacci) es un número en la siguiente secuencia entera: 14, 19, 28, 47, 61, 75, 197, 742, 1104, 1537, 2208, 2580, ...

Numberphile tiene un video que explica cómo calcular un número de Keith. Pero básicamente tomas los dígitos de un número. Súmelos juntos y luego tome los últimos dígitos del número original y agréguelos a la suma del cálculo, enjuague y repita. Y ejemplo para dejarlo claro.

14
1 + 4 = 5
4 + 5 = 9
5 + 9 = 14

Entrada

Un entero

Salida

Verdadero si el número es un número Keith. Falso si no es ..

Smetad Anarkist
fuente
Estrictamente hablando, "un número entero" puede incluir números cero o negativos. Estoy bastante seguro de que ninguno de los dos puede ser un número Keith. ¿Necesitamos dar cuenta de esto?
Iszi
Dependiendo de su solución, los números de un solo dígito podrían aparecer como verdaderos. Por lo tanto, debe verificar los posibles errores en la entrada.
Smetad Anarkist
¿Tiene que salir true/ falseo puede ser algo verdadero / falso ?
Cyoce

Respuestas:

7

GolfScript ( 31 25 caracteres)

..[10base{.{+}*+(\}@*]?0>

Ingrese como un entero en la parte superior de la pila. La salida es 0 (falso) o 1 (verdadero). Demostración en línea que enumera los números Keith hasta 100.

Peter Taylor
fuente
Buena idea con el 0>. Lamentablemente, puedo hacer +1 solo una vez.
Howard
7

Pitón ( 78 75)

a=input()
n=map(int,`a`)
while a>n[0]:n=n[1:]+[sum(n)]
print(a==n[0])&(a>9)

n=n[1:]+[sum(n)]hace toda la magia Toma todos los elementos, excepto el primer elemento de n, se pega en la suma de n(con el primer elemento), luego lo establece en n.

Desearía que pudieras llamar lista un número entero y separar los dígitos.

Devuelve Falsetodas las entradas por debajo de 10. Puede ser 8 caracteres más corto si devuelve True.

beary605
fuente
Puede guardar dos caracteres si compara con en n[0]lugar de n[-1].
Howard
Ahorre cinco más con print 9<a==n[0].
res
n=n[1:]+[sum(n)]puede convertirsen=n[1:]+sum(n),
Cyoce
6

GolfScript, 32 29 caracteres

...[10base\{.{+}*+(\}*]&,\9>&

Una implementación de GolfScript que se puede probar en línea . La entrada se da como elemento superior en la pila y devuelve 0 (es decir, falso) o 1 respectivamente.

Howard
fuente
@PeterTaylor Mira el enlace proporcionado donde hice exactamente eso, y funciona ...
Howard
@PeterTaylor Mirando su solución, incluso podría reducir aún más el número de caracteres en mi enfoque.
Howard
No debo haber actualizado, porque mi comentario es aplicable a la versión 1.
Peter Taylor
4

APL, 36 34 39 36 33 29 27

*+/x={(∇⍣(⊃x>¯1↑⍵))⍵,+/⍵↑⍨-⍴⍕x}⍎¨⍕x←⎕

Salida 1si Keith, de lo 0contrario

¡GolfScript ataca de nuevo!


Editar

+/x={(∇⍣(x>⊢/⍵))⍵,+/⍵↑⍨-⍴⍕x}⍎¨⍕x←⎕

Uso de reducción a la derecha (⊢/ ) en lugar de Take menos 1 ( ¯1↑), guarda directamente 1 carácter e indirectamente salva 1 de Disclose ( )

Explicación

⍎¨⍕x←⎕ toma la entrada evaluada (tratada como un número) y la asigna a x . Lo convierte en una matriz de caracteres (también conocido como "cadena" en otros idiomas) y recorre cada carácter (dígito), convirtiéndolo en un número. Entonces esto resulta en una matriz numérica de los dígitos.

{(∇⍣(x>⊢/⍵))⍵,+/⍵↑⍨-⍴⍕x}es la función principal de "bucle":
+/⍵↑⍨-⍴⍕xtoma los últimos números ⍴⍕x(no. de dígitos x) de la matriz y los suma.
⍵,lo concatena al final de la matriz.
(x>⊢/⍵)compruebe si el último número en la matriz (que aún no se ha +/⍵↑⍨-⍴⍕xconcatenado) es menor xy devuelve 1o 0
∇⍣ejecuta esta función en la nueva matriz muchas veces. Entonces, si el último número es menor que x, esta función se repite. De lo contrario, solo devuelva la nueva matriz

Después de ejecutar la función, la matriz contiene las sumas hasta el punto en que 2 de los números son mayores o iguales que x(por ejemplo 14, generará 1 4 5 9 14 23, 13generará 1 3 4 7 11 18 29)
Finalmente, compruebe si cada número es igual xy genera la suma del binario resultante formación.


Editar

1=+/x={(∇⍣(x>⊢/⍵))⍵,+/⍵↑⍨-⍴⍕x}⍎¨⍕x←⎕

Se agregaron 2 caracteres :-( para hacer la salida 0si la entrada es de un dígito


Otra edición más

+/x=¯1↓{(∇⍣(x>⊢/⍵))1↓⍵,+/⍵}⍎¨⍕x←⎕

Explicación

La función ahora elimina el primer número ( 1↓) de la matriz en lugar de tomar el último ⍴⍕x( ↑⍨-⍴⍕x).
Sin embargo, este enfoque 1=no es adecuado para manejar números de un solo dígito. Por lo tanto, ahora suelta el último número de la matriz antes de verificar la igualdad x, agregando 1 carácter


Lo has adivinado: EDITAR

+/x=1↓{1↓⍵,+/⍵}⍣{x≤+/⍵}⍎¨⍕x←⎕

Se compara xcon el elemento recién agregado en lugar del último elemento anterior, por lo que xes suficiente colocar el primer elemento (en lugar del último) antes de verificar la igualdad , guardando un signo menos. Guarda otros 3 utilizando otra forma del operador Power ( )

Y aparece una respuesta de 25 char gs (Orz)


Última edición

x∊1↓{1↓⍵,+/⍵}⍣{x≤+/⍵}⍎¨⍕x←⎕

No puedo creer que me haya perdido eso.
No puedo jugar más al golf.

TwiNight
fuente
1
Usted puede conseguir esto a 24 caracteres: x∊{1↓⍵,+/⍵}⍣{x≤⊃⍺}⍎¨⍕x←⎕. En la función de potencia, es el valor "después".
Marinus
2

Lisp común, 134

CL puede ser bastante ilegible a veces.

(defun k(n)(do((a(map'list #'digit-char-p(prin1-to-string n))(cdr(nconc a(list(apply'+ a))))))((>=(car a)n)(and(> n 9)(=(car a)n)))))

Algunos formatos para evitar el desplazamiento horizontal:

(defun k(n)
  (do
    ((a(map'list #'digit-char-p(prin1-to-string n))(cdr(nconc a(list(apply'+ a))))))
    ((>=(car a)n)(and(> n 9)(=(car a)n)))))

Prueba:

(loop for i from 10 to 1000
      if (k i)
      collect i)

=> (14 19 28 47 61 75 197 742)
daniero
fuente
1

F # - 184 caracteres

Espero que esté bien que participe en mi propio desafío.

let K n=
let rec l x=if n<10 then false else match Seq.sum x with|v when v=n->true|v when v<n->l(Seq.append(Seq.skip 1 x)[Seq.sum x])|_->false
string n|>Seq.map(fun c->int c-48)|>l

Editar Se corrigió un error relacionado con números pequeños.

revs anarquista Smetad
fuente
Está perfectamente bien :)
beary605
Su solución devuelve verdadero para n <10, que creo que debería ser falso.
Howard
Tienes razón. Debería mirar en eso.
Smetad Anarkist
1

K, 55

{(x>9)&x=*|a:{(1_x),+/x}/[{~(x~*|y)|(+/y)>x}x;"I"$'$x]}

.

k)&{(x>9)&x=*|a:{(1_x),+/x}/[{~(x~*|y)|(+/y)>x}x;"I"$'$x]}'!100000
14 19 28 47 61 75 197 742 1104 1537 2208 2580 3684 4788 7385 7647 7909 31331 34285 34348 55604 62662 86935 93993
tmartin
fuente
1

PowerShell: 120 128 123 111 110 97

$j=($i=read-host)-split''|?{$_};While($x-lt$i){$x=0;$j|%{$x+=$_};$null,$j=$j+$x}$x-eq$i-and$x-gt9

$i=read-host toma información del usuario, la almacena en $ i.

$j=(... )-split''|?{$_}divide los dígitos de $ i en una matriz y lo almacena en $ j.

Gracias a Rynant por señalar que -ne''es innecesario.

While($x-lt$i) establece el siguiente ciclo similar a Fibonnaci para que se ejecute hasta que la variable suma, $ x, alcance o exceda $ i.

$x=0 pone a cero $ x, por lo que está listo para ser usado para sumar (necesario para cuando el ciclo vuelve).

$j|%{$x+=$_} usa un bucle ForEach-Object para sumar los valores de $ j a $ x.

$null,$j=$j+$x desplaza los valores en $ j a la izquierda, descartando el primero, mientras agrega $ x.

¡Hurra! Finalmente descubrí una forma más corta de hacer shift-and-append, ¡y obtuve este script por debajo de 100!

$x-eq$i después de que se completa el ciclo while, prueba si el valor de suma, $ x, es igual al valor inicial, $ i, generalmente indicativo de un número Keith.

-and$x-gt9 invalida números de un solo dígito, cero y números negativos, que no pueden ser números Keith.

Este script es un poco "desordenado". Puede manejar con gracia $ i y $ j sobrantes, pero deberá borrar $ x entre ejecuciones.

Gracias a Keith Hill y mjolinor por algunos métodos para dividir números en dígitos que se usaron en versiones anteriores de este script. Si bien no están en la versión final, proporcionaron una gran experiencia de aprendizaje.

Iszi
fuente
Puede eliminar el -ne''para que sea justo ?{$_}.
Rynant
Gracias @Rynant. Parece que también puedo recortarlo uno más reemplazándolo $i=read-host;$j=$i-split''|?{$_}'con $j=($i=read-host)-split''|?{$_}.
Iszi
0

Rubí, 82

def keith?(x)
  l="#{x}".chars.map &:to_i
  0while(l<<(s=l.inject :+)).shift&&s<x
  (s==x)&l[1]
end

El sospechoso Python es una mejor herramienta para este.

histocrat
fuente
0

C, 123

k(v){
    int g[9],i,n,s,t=v;
    for(n=s=0;t;t/=10)s+=g[n++]=t%10;
    for(i=n;s<v;){
        i=(i+n-1)%n;
        t=g[i];g[i]=s;s=s*2-t;
    }
    return n>1&&s==v;
}

prueba mediante arnés:

main(i){
    for(i=0;i<20000;i++)
        if(k(i)) printf("%d ",i);
}

da:

14 19 28 47 61 75 197 742 1104 1537 2208 2580 3684 4788 7385 7647 7909
conejo bebé
fuente
Puede reemplazar i=(i+n-1)%n;t=g[i];g[i]=s;s=s*2-t;con i+=n-1;t=g[i%n];g[i%n]=s;s+=s-t;y guardar dos caracteres.
schnaader
0

R, 116

Estafa de Python:

a=scan();n=as.numeric(strsplit(as.character(a),"")[[1]]);while(a>n[1])n=c(n[-1],sum(n));if((n[1]==a)&&(a>9))T else F
Paolo
fuente
0

Perl, 90

sub k{$-=shift;$==@$=split//,$-;push@$,eval join'+',@$[-$=..-1]while@$[-1]<$-;grep/$-/,@$}

Un ejercicio divertido! ¡Sé que es una publicación antigua pero noté que faltaba Perl!

Estoy seguro de que puedo mejorar la forma en que construyo esto al digerir las otras respuestas más a fondo, ¡así que probablemente vuelva a visitar esto!

Dom Hastings
fuente
0

Smalltalk - 136 char

 [:n|s:=n asString collect:[:c|c digitValue]as:OrderedCollection.w:=s size.[n>s last]whileTrue:[s add:(s last:w)sum].^(s last=n and:n>9)]

Enviar este bloque value:

Paul Richter
fuente
0

Java - 1437

import java.io.*;
class keith
{
    public int reverse(int n)
    {
        int i,c=0;
        while(n>0)
        {
            c=(c*10)+(n%10);
            n/=10;
        }
        return(c);
    }
    public int countdigit(int n)
    {
        int i,c=0;
        while(n>0)
        {
            c++;
            n/=10;
        }
        return(c);
    }
    public void keith_chk()throws IOException
    {
        BufferedReader br=new BufferedReader(
        new InputStreamReader(System.in));
        int n,digi,r,p=0,a,tot=0,i;
        System.out.print("Enter number :-");
        n=Integer.parseInt(br.readLine());
        digi=countdigit(n);

        int ar[]=new int[digi+1];
        r=reverse(n);
        while(r>0)
        {
            a=r%10;
            ar[p++]=a;
            tot=tot+a;
            r/=10;
        }
        ar[p]=tot;
        while(true)
        {
            for(i=0;i<=p;i++)
            System.out.print(ar[i]+"\t");
            System.out.println(); 
            if(tot == n)
            {
                System.out.print("Keith Number....");
                break;
            }
            else if(tot > n)
            {
                System.out.print("Not Keith Number.....");
                break;
            }
            tot=0;
            for(i=1;i<=p;i++)
            {
                ar[i-1]=ar[i];
                tot=tot+ar[i];
            }
            ar[p]=tot;
        }
    }
}
mousami
fuente
3
Bienvenido a CodeGolf.SE! Dado que esta pregunta es code-golf , debe golf su código (eliminar espacios en blanco, nuevas líneas ...)
Vereos
0

Python3 104

#BEGIN_CODE
def k(z):
 c=str(z);a=list(map(int,c));b=sum(a)
 while b<z:a=a[1:]+[b];b=sum(a)
 return(b==z)&(len(c)>1)
#END_CODE score: 104

print([i for i in filter(k, range(1,101))])  #[14, 19, 28, 47, 61, 75]

Y es una función;)

gcq
fuente
0

Python - 116 caracteres

No soy realmente un experto en codegolf, así que ahí lo tienes, mi primer intento.

x=input();n=`x`;d=[int(i)for i in n];f=d[-1]
while f<x:d+=[sum(d[-len(n):])];f=d[-1]
if f==x>13:print 1
else:print 0

Realice 2 cambios para una función:

  • Cambiar printareturn
  • Asignar xpara ser el parámetro

PD I second @ beary605- agregue un incorporado para separar los dígitos / caracteres / lo que sea.

Dan el hombre
fuente
0

Rubí (con POO)

class Recreationalmathematics
def Check_KeithSequence(digit) 
    sequence,sum=digit.to_s.split(//).to_a,0
    while(sum<digit) do
        sum=0
        sequence.last(digit.to_s.size).each{|v|  sum=sum+v.to_i}
        sequence<<sum
    end 
    return (sum==digit)?"true":"false" 
end
end
test = Recreationalmathematics.new
puts test.Check_KeithSequence(197)
puts test.Check_KeithSequence(198)
principianteProg
fuente