Проверьте, если задано число, если число Кит


14

Так как числа и последовательности Фибоначчи кажутся популярной темой для гольф-кода, я подумал, что это может быть забавная задача - кодировать гольф с числами Кейта .

Поэтому я предлагаю задачу, состоящую в том, чтобы создать функцию, которая принимает целое число и возвращает true или false в зависимости от того, является число Кейтом или нет.

Подробнее о числах Кейта

В развлекательной математике число Кейта или число повторяющихся чисел (сокращение от повторяющихся цифр, подобных Фибоначчи) представляет собой число в следующей целочисленной последовательности: 14, 19, 28, 47, 61, 75, 197, 742, 1104, 1537, 2208, 2580,…

У Numberphile есть видео, объясняющее, как рассчитать число Кейта. Но в основном вы берете цифры номера. Сложите их вместе, а затем возьмите последние цифры исходного числа и добавьте их к сумме расчета, промойте и повторите. И пример, чтобы было понятно.

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

вход

Целое число

Выход

Истинно, если число является числом Кейта. Ложь, если это не ..


Строго говоря, «целое число» может включать ноль или отрицательные числа. Я уверен, что ни один из них не может быть Китом. Нужно ли нам это учитывать?
Изи

В зависимости от вашего решения однозначные числа могут отображаться как истина. Поэтому вы должны проверить на возможные ошибки при вводе.
Сметад Анаркист

Должен ли он выводить true/ falseили это может быть что-то правдивое / фальшивое ?
Cyoce

Ответы:


7

GolfScript ( 31 25 символов)

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

Вводится как целое число сверху стека. Выходное значение равно 0 (false) или 1 (true). Демо онлайн, в котором перечислены номера Кейта до 100.


Хорошая идея с 0>. К сожалению я могу +1 только один раз.
Говард

7

Питон ( 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)]делает всю магию. Он берет каждый элемент, но первый элемент n, привязывается к сумме n(с первым элементом), а затем устанавливает его на n.

Я хотел бы, чтобы вы могли вызвать listцелое число и разделить цифры.

Возвращает Falseна всех входах ниже 10. Может быть на 8 символов короче, если он вернулся True.


Вы можете сохранить два символа, если вы сравните с n[0]вместо n[-1].
Говард

Сэкономьте еще пять с print 9<a==n[0].
Res

n=n[1:]+[sum(n)]может статьn=n[1:]+sum(n),
Cyoce

6

GolfScript, 32 29 символов

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

Реализация GolfScript, которую можно протестировать онлайн . Входные данные задаются как верхний элемент в стеке и возвращают 0 (т. Е. False) или 1 соответственно.


@PeterTaylor Посмотрите на ссылку, где я сделал именно это - и это работает ...
Говард

@PeterTaylor Глядя на ваше решение, я даже мог бы уменьшить количество символов в моем подходе.
Говард

Я, должно быть, не обновился, потому что мой комментарий применим к версии 1.
Питер Тейлор

4

APL, 36 34 39 36 33 29 27

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

Выведите, 1если Кейт, в 0противном случае

GolfScript снова бьет!


редактировать

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

Использование правого сокращения (⊢/ ) вместо Take минус 1 (¯1↑ ), непосредственно сохраняя 1 символ и косвенно сохраняет 1 от Disclose ( )

объяснение

⍎¨⍕x←⎕ принимает оцененный ввод (рассматривается как число) и присваивает его x . Преобразует его в массив символов (также называемый «строка» в других языках) и циклически перебирает каждый символ (цифру), преобразовывая его в число. Таким образом, это приводит к числовому массиву цифр.

{(∇⍣(x>⊢/⍵))⍵,+/⍵↑⍨-⍴⍕x}является основной функцией цикла:
+/⍵↑⍨-⍴⍕xберет последние ⍴⍕x(количество цифр в x) числа из массива и суммирует их.
⍵,объединяет его до конца массива.
(x>⊢/⍵)проверить, +/⍵↑⍨-⍴⍕xне меньше ли последнее число в массиве (которое еще не объединено) xи возвращает 1или0
∇⍣ выполняет эту функцию для нового массива много раз. Поэтому, если последнее число меньше, чем xэта функция повторяется. В противном случае просто верните новый массив

После выполнения функции массив содержит суммы до точки, где 2 числа больше или равны x(например 14, сгенерируют 1 4 5 9 14 23, 13сгенерируют 1 3 4 7 11 18 29).
Наконец, проверьте, равно ли каждое числоx и выведите сумму полученного двоичного кода. массив.


редактировать

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

Добавлены 2 символа :-( чтобы сделать вывод, 0если ввод однозначный


Еще одно редактирование

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

объяснение

Функция теперь удаляет первое число ( 1↓) из массива вместо взятия last ⍴⍕x( ↑⍨-⍴⍕x).
Однако такой подход 1=не позволяет обрабатывать однозначные числа. Так что теперь он удаляет последнее число из массива, прежде чем проверять равенство x, добавляя 1 символ


Вы догадались: РЕДАКТИРОВАТЬ

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

Сравнивает xс вновь добавленным элементом вместо старого последнего элемента, поэтому отбрасывает первый (а не последний) элемент перед проверкой равенства наx , сохранив знак минус. Сохраняет еще 3 с помощью другой формы оператора Power ( )

И появляется ответ с 25 знаками (Orz)


Последнее редактирование

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

Не могу поверить, что я пропустил это.
Больше не могу играть в гольф.


1
Вы можете получить это до 24 символов: x∊{1↓⍵,+/⍵}⍣{x≤⊃⍺}⍎¨⍕x←⎕. В степенной функции это значение «после».
Маринус

2

Common Lisp, 134

CL иногда может быть совершенно нечитаемым.

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

Некоторое форматирование, чтобы избежать горизонтальной прокрутки:

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

Тестовое задание:

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

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

1

F # - 184 символа

Я надеюсь, что все в порядке, что я буду участвовать в моем собственном соревновании.

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

Редактировать Исправлена ​​ошибка, связанная с небольшими числами.


Это совершенно нормально :)
beary605

Ваше решение возвращает true для n <10, что, по моему мнению, должно быть false.
Говард

Вы правы. Я должен посмотреть на это.
Сметад Анаркист

1

К, 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 принимает данные от пользователя, сохраняет их в $ i.

$j=(... )-split''|?{$_}разбивает цифры из $ i в массив и сохраняет его в $ j.

Спасибо Rynant за указание на то, что -ne''это не нужно.

While($x-lt$i) устанавливает выполнение следующего цикла Фибоначчи, пока переменная суммы, $ x, не достигнет или не превысит $ i.

$x=0 обнуляет $ x, поэтому он готов к использованию для суммирования (необходимо, когда цикл возвращается).

$j|%{$x+=$_} использует цикл ForEach-Object для суммирования значений из $ j в $ x.

$null,$j=$j+$x сдвигает значения в $ j влево, отбрасывая первое, добавляя $ x.

Ура! Я наконец-то нашел более короткий способ сделать shift-and-append и получил этот скрипт меньше 100!

$x-eq$i после завершения цикла while проверяется, равно ли значение суммы, $ x, начальному значению, $ i - обычно указывает число Кейта.

-and$x-gt9 делает недействительными однозначные числа, ноль и отрицательные числа, которые не могут быть числами Кейта.

Этот скрипт немного "грязный". Он может корректно обрабатывать остатки $ i и $ j, но вам нужно очистить $ x между запусками.

Спасибо Кита Хиллу и Мьолинору за некоторые методы разбиения чисел на цифры, которые использовались в более ранних версиях этого скрипта. Хотя они не в финальной версии, они обеспечили большой опыт обучения.


Вы можете удалить -ne''так, что это просто ?{$_}.
Rynant

Спасибо @Rynant. Похоже, я также могу урезать его, заменив $i=read-host;$j=$i-split''|?{$_}'на $j=($i=read-host)-split''|?{$_}.
Изи

0

Руби, 82

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

Подозреваю, что Python - лучший инструмент для этого.


0

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

тест через жгут:

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

дает:

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

Вы можете заменить i=(i+n-1)%n;t=g[i];g[i]=s;s=s*2-t;с i+=n-1;t=g[i%n];g[i%n]=s;s+=s-t;и сохранить два символа.
Schnaader

0

R 116

Плагиат 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

0

Perl, 90

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

Веселое упражнение! Я знаю, что это старый пост, но я заметил, что perl отсутствует!

Я уверен, что смогу улучшить способ, которым я построю это, переварив другие ответы более тщательно, так что я, вероятно, вернусь к этому!


0

Smalltalk - 136 символов

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

Отправить этот блок value:


0

Ява - 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
Добро пожаловать в CodeGolf.SE! Так как этот вопрос относится к коду-гольфу , вы должны поиграть в свой код (убрать пробелы, новые строки ...)
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]

И это функция;)


0

Питон - 116 символов

Не совсем эксперт в Codegolf, так что у вас есть моя первая попытка.

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

Сделайте 2 изменения для функции:

  • Изменить printнаreturn
  • Назначить xв качестве параметра

PS Я второй @ beary605 - добавить встроенную для разделения цифр / символов / что угодно.


0

Рубин (с ООП)

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)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.