Prova se dato numero se un numero Keith


14

Dato che i numeri e le sequenze di Fibonacci sembrano un argomento popolare per il golf del codice, ho pensato che potrebbe essere una sfida divertente programmare il golf con i numeri di Keith .

Quindi propongo una sfida che consiste nel creare una funzione che accetta un numero intero e restituisce un vero o falso a seconda che il numero sia un numero di Keith o meno.

Maggiori informazioni sui numeri di Keith

In matematica ricreativa, un numero di Keith o un numero di riconfigurazione (abbreviazione di cifra ripetitiva simile a Fibonacci) è un numero nella seguente sequenza intera: 14, 19, 28, 47, 61, 75, 197, 742, 1104, 1537, 2208, 2580, ...

Numberphile ha un video che spiega come calcolare un numero Keith. Ma fondamentalmente prendi le cifre di un numero. Aggiungili insieme, quindi prendi le ultime cifre del numero originale e aggiungile alla somma del calcolo, risciacqua e ripeti. Ed esempio per chiarire.

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

Ingresso

Un numero intero.

Produzione

Vero se il numero è un numero Keith. Falso se non è ..


A rigor di termini, "un numero intero" può includere numeri zero o negativi. Sono abbastanza sicuro che nessuno dei due può essere un numero di Keith. Dobbiamo tener conto di questo?
Iszi,

A seconda della soluzione, i numeri a una cifra potrebbero apparire come veri. Quindi dovresti controllare potenziali errori nell'input.
Smetad Anarkist,

Deve produrre true/ falseo può essere qualcosa di vero / falso ?
Cyoce,

Risposte:


7

GolfScript ( 31 25 caratteri)

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

Immettere come numero intero in cima allo stack. L'output è 0 (falso) o 1 (vero).Demo online che elenca i numeri di Keith fino a 100.


Bella idea con il 0>. Purtroppo posso fare +1 solo una volta.
Howard,

7

Python ( 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)]fa tutta la magia. Prende ogni oggetto tranne il primo oggetto n, si attacca alla somma di n(con il primo oggetto), quindi lo imposta su n.

Vorrei che tu potessi chiamare listun numero intero e che le cifre fossero separate.

Restituisce Falsesu tutti gli input inferiori a 10. Può essere più breve di 8 caratteri se restituito True.


È possibile salvare due caratteri se si confronta con n[0]invece di n[-1].
Howard,

Risparmia altri cinque con print 9<a==n[0].
ris.

n=n[1:]+[sum(n)]può diventaren=n[1:]+sum(n),
Cyoce il

6

GolfScript, 32 29 caratteri

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

Un'implementazione GolfScript che può essere testata online . L'input viene dato come elemento superiore nello stack e restituisce rispettivamente 0 (ovvero false) o 1.


@PeterTaylor Guarda il link fornito dove ho fatto esattamente questo - e funziona ...
Howard,

@PeterTaylor Esaminando la tua soluzione, ho anche potuto ridurre ulteriormente il numero di caratteri nel mio approccio.
Howard,

Non devo aver effettuato l'aggiornamento, perché il mio commento è applicabile alla versione 1.
Peter Taylor,

4

APL, 36 34 39 36 33 29 27

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

Produzione 1 se Keith, 0altrimenti

GolfScript colpisce ancora !!


modificare

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

Utilizzando la riduzione destra ( ⊢/) anziché Take meno 1 ( ¯1↑), salvando direttamente 1 carattere e indirettamente 1 da Disclose ( )

Spiegazione

⍎¨⍕x←⎕prende l'input valutato (trattato come un numero) e lo assegna a x. Lo converte in un array di caratteri (noto anche come "stringa" in altre lingue) e passa in rassegna ciascun carattere (cifra), convertendolo in un numero. Quindi questo si traduce in una matrice numerica delle cifre.

{(∇⍣(x>⊢/⍵))⍵,+/⍵↑⍨-⍴⍕x}è la funzione "loop" principale:
+/⍵↑⍨-⍴⍕xprende gli ultimi ⍴⍕x(numero di cifre x) dall'array e li somma.
⍵,lo concatena alla fine dell'array.
(x>⊢/⍵)controlla se l'ultimo numero sull'array (che non ha +/⍵↑⍨-⍴⍕xancora concatenato) è più piccolo di xe restituisce 1o 0
∇⍣esegue questa funzione sul nuovo array più volte. Quindi, se l'ultimo numero è inferiore a x, questa funzione ricorre. Altrimenti restituisci semplicemente il nuovo array

Dopo aver eseguito la funzione, l'array contiene le somme fino al punto in cui 2 dei numeri sono maggiori o uguali a x(ad esempio 14genererà 1 4 5 9 14 23, 13genererà 1 3 4 7 11 18 29)
Infine controlla se ogni numero è uguale xe genera la somma del binario risultante Vettore.


modificare

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

Aggiunti 2 caratteri :-( per creare output 0se l'input è di una cifra


Ancora un'altra modifica

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

Spiegazione

La funzione ora rilascia il primo numero ( 1↓) dall'array invece di prendere l'ultimo ⍴⍕x( ↑⍨-⍴⍕x).
Tuttavia, questo approccio 1=non è adeguato per gestire numeri a una cifra. Quindi ora rilascia l'ultimo numero dall'array prima di verificare l'uguaglianza in x, aggiungendo 1 carattere


Hai indovinato: EDIT

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

Confronta xcon l'elemento appena aggiunto invece del vecchio ultimo elemento, quindi xè sufficiente far cadere il primo (anziché l'ultimo) elemento prima di verificare l'uguaglianza , salvando un segno meno. Salva altri 3 utilizzando un'altra forma di Power operator ( )

E appare una risposta di 25 caratteri gs (Orz)


Ultima modifica

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

Non riesco a credere che mi sia perso.
Non posso più giocare a golf.


1
È possibile ottenere questo fino a 24 caratteri: x∊{1↓⍵,+/⍵}⍣{x≤⊃⍺}⍎¨⍕x←⎕. Nella funzione di alimentazione, è il valore "dopo".
Marin il

2

Lisp comune, 134

Il CL può essere abbastanza illeggibile a volte.

(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)))))

Alcune formattazioni per evitare lo scorrimento orizzontale:

(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)))))

Test:

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

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

1

F # - 184 caratteri

Spero sia ok che parteciperò alla mia sfida.

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

Modifica Risolto un bug relativo ai numeri piccoli.


Va benissimo :)
beary605,

La tua soluzione restituisce true per n <10 che penso dovrebbe essere falsa.
Howard,

Hai ragione. Dovrei esaminarlo.
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

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 riceve input dall'utente, lo memorizza in $ i.

$j=(... )-split''|?{$_}suddivide le cifre da $ i in un array e le memorizza in $ j.

Grazie a Rynant per aver sottolineato che -ne''non è necessario.

While($x-lt$i) imposta il seguente ciclo simile a Fibonnaci per l'esecuzione fino a quando la variabile somma, $ x, raggiunge o supera $ i.

$x=0 azzera $ x, quindi è pronto per essere utilizzato per il riepilogo (necessario per quando il loop ritorna in giro).

$j|%{$x+=$_} utilizza un ciclo ForEach-Object per sommare i valori da $ j a $ x.

$null,$j=$j+$x sposta i valori in $ j a sinistra, scartando il primo e aggiungendo $ x.

Sìì! Alla fine ho capito un modo più breve di fare shift-and-append e ho ottenuto questo script con meno di 100!

$x-eq$i al termine del ciclo while, verifica se il valore della somma, $ x, è uguale al valore iniziale, $ i - generalmente indicativo di un numero di Keith.

-and$x-gt9 invalida i numeri a una cifra, zero e negativi, che non possono essere Keith Numbers.

Questo script è un po '"disordinato". Può gestire con grazia $ i e $ j rimanendo, ma dovrai cancellare $ x tra le esecuzioni.

Grazie a Keith Hill e mjolinor per alcuni metodi di suddivisione dei numeri in cifre che sono stati utilizzati nelle versioni precedenti di questo script. Sebbene non siano nella versione finale, hanno fornito un'ottima esperienza di apprendimento.


Puoi rimuoverlo in -ne''modo che sia giusto ?{$_}.
Rynant,

Grazie @Rynant. Sembra che posso anche ridimensionarlo ancora una volta sostituendolo $i=read-host;$j=$i-split''|?{$_}'con $j=($i=read-host)-split''|?{$_}.
Iszi,

0

Ruby, 82

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

Sospettare che Python sia uno strumento migliore per questo.


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

test tramite imbracatura:

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

dà:

14 19 28 47 61 75 197 742 1104 1537 2208 2580 3684 4788 7385 7647 7909

È possibile sostituire 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;e salvare due caratteri.
Schnaader,

0

R, 116

Python fregatura:

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

0

Perl, 90

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

Un esercizio divertente! So che è un vecchio post ma ho notato che mancava il perl!

Sono sicuro di poter migliorare il modo in cui lo costruisco digerendo le altre risposte in modo più approfondito, quindi probabilmente lo rivisiterò!


0

Smalltalk - 136 caratteri

 [: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)]

Invia questo blocco value:


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

3
Benvenuto in CodeGolf.SE! Poiché questa domanda è code-golf , dovresti golf il tuo codice (rimuovi spazi bianchi, nuove righe ...)
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]

Ed è una funzione;)


0

Python - 116 caratteri

Non proprio un esperto di Codegolf, quindi il gioco è fatto - il mio primo tentativo.

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

Apporta 2 modifiche per una funzione:

  • Cambia printinreturn
  • Assegna xcome parametro

PS I secondo @ beary605- aggiungi un built-in per separare le cifre / i caratteri / qualunque cosa.


0

Ruby (con OOP)

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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.