Проверьте номер на нарциссизм


53

Нарциссический Номер представляет собой число , которое является суммой собственных цифр, каждый из возведенных в степень числа цифр.

Например, возьмем 153 (3 цифры):

1 3 + 5 3 + 3 3 = 1 + 125 + 27 = 153

1634:

1 4 + 6 4 + 3 4 + 4 4 = 1 + 1296 + 81 + 256 = 1634

Соревнование:

Ваш код должен принимать ввод от пользователя и выводить True или False в зависимости от того, является ли данное число нарциссическим числом.

Проверка ошибок на наличие текстовых строк или других неверных входных данных не требуется. 1 или 0 для выхода приемлемо. Код, который просто генерирует список нарциссических чисел или проверяет ввод пользователя по списку, не подходит.

OEIS A005188


3
Это нормально, если я выведу, Trueесли это такое число, но что-нибудь еще (в данном случае само число), если нет?
devRicher

Ответы:


39

APL (15)

∆≡⍕+/(⍎¨∆)*⍴∆←⍞

Выводит, 1если true и 0если false.

Объяснение:

  • ∆←⍞: прочитать строку (как символы), сохранить в
  • (⍎¨∆)*⍴∆: оцените каждого персонажа и поднимите его до уровня власти⍴∆
  • ∆≡⍕+/: посмотрите, равно ли входное значение строкового представления суммы этих

9
что я только что прочитал
Jbwilliams1

4
@LagWagon Божий язык
августа

21

GolfScript, 16 символов

~.`:s{48-s,?-}/!

Входные данные должны быть даны в STDIN, выходные данные - 0 или 1, указывающие ненарцистическое / нарциссическое число.

Пояснение к коду:

~              # Evaluate the input to get a number
.              # Accumulator (initially the number itself)
`:s            # Convert number to string and assign to variable s
{              # Loop over characters of the string
  48-          # Reduce character value by 48
  s,           # Push length of input number
  ?            # Power
  -            # Subtract result from accumulator
}/
!              # Not! (i.e. iff accumulator was zero it was a narcissistic number)

Я сделал двойной дубль на `` ~ .` ``, но, кажется, улучшить невозможно. Хороший.
Питер Тейлор


14

Perl, 38 символов

perl -lpe '$@=y///c;$s+=$_**$@for/./g;$_=$_==$s'

Довольно простая реализация.

Вот немного другая версия, которая умещается в 35 символов:

perl -lpe '$@=y///c;$s+=$_**$@for/./g;$_-=$s'

Эта версия выводит ложное значение, если вход является нарциссическим, в противном случае выводится (допустимое для Perl) истинное значение. Кто-то может возразить, что эта обратная версия находится в пределах описания вызова, но, подумав, я решил не делать этого. Я не так отчаянно желаю улучшить свой счет. Все же.


«Проверка ошибок на наличие текстовых строк или других неверных входных данных не требуется». Так почему бы не предположить, что ввод будет действительным числом без завершающей строки? echo -n 153 | perl -pe '…'будет работать без -l.
manatwork

Я думаю, до тех пор, пока вы определяете, каковы ваши истинные и ложные выводы, это должно быть законно
Cruncher

Строго говоря, формулировка текста вызова оставляет некоторую двусмысленность относительно того, что должно означать True / False или 0/1, поэтому я позволю этому пройти. Однако другой сценарий равной длины, который возвращает true для нарциссических значений, имеет преимущество.
Изи

Та же идея, но короче:perl -pe'map$s+=$_**@y,@y=/./g;$_=$_==$s'
msh210

13

J, 23 знака

(".=+/@("."0^#))(1!:1)1

(1!:1)1 это ввод с клавиатуры (возвращающий строку).

".преобразует ввод в число; "0определяет ранг (размерность) 0, другими словами, беря каждый символ и преобразовывая его в число.

^является степенной функцией и #является функцией длины, таким образом, каждая цифра переводится в степень длины строки (эквивалентно количеству цифр).

+/это просто сумма, и =сравнивает сумму и число.


2
«Ваш код должен принимать входные данные от пользователя и выводить True или False в зависимости от того, является ли данное число нарциссическим числом». (выделение мое)
Джон Дворак

@JanDvorak Мой плохой - добавлен ввод с клавиатуры.
rationalis

12

Рубин, 34 + 5 = 39

С флагами командной строки

ruby -nlaF|

Бегать

p eval [$F,0]*"**#{~/$/}+"+"==#$_"

Выходы истина или ложь.


3
Это могут быть самые рубиновые флаги, которые я когда-либо видел в законном кодовом гольфе: P
Doorknob

11

R 71 69 66 56 48

Уменьшено на 8 байт благодаря @Giuseppe ! Идея заключалась в том, чтобы выполнить целочисленное деление перед операцией по модулю.

i=nchar(a<-scan()):0;a==sum((a%/%10^i%%10)^i[1])

(3 года) старая версия с соответствующим объяснением:

i=nchar(a<-scan()):1;a==sum(((a%%10^i)%/%10^(i-1))^i[1])

a<-scan()принимает в качестве входных данных число (целое, вещественное, ...) (скажем, 153для примера).
iстановится вектором, содержащим от 3 до 1 (количество символов a3).
%%векторизовано так a%%10^iозначает aпо модулю 1000, 100 и 10: поэтому дает 153, 53, 3.
(a%%10^i)%/%10^(i-1)это целочисленное деление этого вектора на 100, 10, 1: следовательно, 1, 5, 3.
Мы возводим это с первым элементом iкоторого является количество символов (здесь цифр) a, то есть 3, таким образом, давая вектор, содержащий 1, 125, 27то, что мы sumи сравниваем a.


Всегда ли округляется целочисленное деление? В противном случае вы можете столкнуться с проблемами, например, 370 (нарциссическое число) превратится в 4,7,0 (что вернет false) или 270 (не нарциссическое), превратившись в 3,7,0 (вернет true).
Изи

Целочисленное деление не округляется ... Целочисленное деление 370 на 100 равно 3 с остатком 70, а не 3,70.
plannapus

1
48 байт ... кто-то столкнулся с этим на домашней странице!
Джузеппе

9

Python 3, 56 байт

Не очень запутанное, но простое решение.

s = input()
print(int(s)==sum(int(c)**len(s)for c in s))

1
В [и ]нет необходимости, и вы можете оставить место перед forтоже, так:sum(int(c)**len(s)for c in s)
marinus

Это потрясающе! Спасибо за чаевые.
Danmcardle

1
Вы можете сохранить два символа, удалив пробелы внутри, s = input()и еще один, переместив его в 2.7, где printэто не функция.
Бен

Хороший вопрос, отредактировано.
Данмкардл

Я думаю, вы должны указать, что добавление фигурных скобок print(следовательно, на один символ больше) сделало бы это действительным решением Python 2.x и Python 3.x.
Мартин Тома

8

PHP, 80 74 66 символов

Очень простое решение PHP:

<?for(;$i<$l=strlen($a=$argv[1]);)$s+=pow($a[$i++],$l);echo$s==$a;

Предполагается, что error_reportingон не включает уведомления, в противном случае потребуется несколько дополнительных символов для инициализации $s=0;и $i=0.

Спасибо @manatwork за сокращение многих символов.


Не назначайте $ a и $ l в отдельных выражениях. <?for($i=0;$i<$l=strlen($a=$argv[1]);$i++){$s+=pow($a[$i],$l);}echo$s==$a;короче
manatwork

Поскольку у вас уже есть оператор, который генерирует уведомление, просто добавьте еще один: удалите инициализацию переменной управления цикла. Увеличение управляющей переменной цикла также не обязательно должно быть отдельным оператором. И брекеты точно не нужны <?for(;$i<$l=strlen($a=$argv[1]);)$s+=pow($a[$i++],$l);echo$s==$a;.
manatwork

@manatwork: Спасибо за теплый прием в Codegolf :)
Влад Преда

Можно сыграть в гольфfor(;$i<$l=strlen($a=$argn);)$s+=$a[$i++]**$l;echo$s==$a;
Йорг Хюльсерманн

8

Dc: 48 символов

[1pq]Sr?d0rdZSz[d10/r10%lz^rSh+Lhd0!=c]dScx+=r0p

Образец прогона:

bash-4.1$ dc -e '[1pq]Sr?d0rdZSz[d10/r10%lz^rSh+Lhd0!=c]dScx+=r0p' <<< '153'
1

bash-4.1$ dc -e '[1pq]Sr?d0rdZSz[d10/r10%lz^rSh+Lhd0!=c]dScx+=r0p' <<< '1634'
1

bash-4.1$ dc -e '[1pq]Sr?d0rdZSz[d10/r10%lz^rSh+Lhd0!=c]dScx+=r0p' <<< '2013'
0

На самом деле никогда не использовал dc, за исключением безумных опечаток при попытке написатьcd
Стэн Струм

8

К, 24 23

{x=+/xexp["I"$'a]@#a:$x}

Бритый 1 символ с переупорядочением

{x=+/{x xexp#x}"I"$'$x}

8

R, 53 байта

sum(scan(t=gsub("(.)","\\1 ",x<-scan()))^nchar(x))==x

gsubРегулярное выражение вставляет пробелы между символами, так что scanфункция будет иметь возможность прочитать номер в вектор цифр.


+1 я бы никогда не подумал сделать это, это замечательно.
plannapus


6

Powershell, 75 63 62 60 58

Редактировать: Обновлено за комментарий @ Iszi (примечание: это рассчитывает на несуществующий )$x

Редактировать: Добавлены изменения @ Данко.

[char[]]($x=$n=read-host)|%{$x-="$_*"*$n.length+1|iex};!$x

58 56 символов

Если ввод ограничен 10 цифрами (включает все int32)

($x=$n=read-host)[0..9]|%{$x-="$_*"*$n.length+1|iex};!$x

Мне было интересно, собирается ли кто-нибудь сделать PowerShell раньше, чем я.
Изи

Сохраните 12 символов, добавив другую переменную $xи используя ее +=для суммирования вместо measure -sumпроверки $x-eq$n.
Изи

1
61 символ:($x=$n=read-host)-split''|%{$x-=[math]::pow($_,$n.length)};!$x
Данко Дурбич

1
@ DankoDurbić, Ницца! Типовое принуждение часто пригодится при игре в гольф с кодом PoSh. Я только получаю 62, хотя, когда я бегу'($x=$n=read-host)-split""|%{$x-=[math]::pow($_,$n.length)};!$x'.length
Rynant

1
@Rynant Хорошая мысль. Я проверил вашу проверку длины в PowerShell и также получил 62. При аналогичной проверке длины по отношению к реальному сценарию он достигает 61. Это, вероятно, из-за того, как PowerShell обрабатывает то, ''что вы заменили ''. Я взял исходный скрипт в Excel, чтобы перепроверить =LEN("($x=$n=read-host)-split''|%{$x-=[math]::pow($_,$n.length)};!$x")и получил 62 также. Конечно, мы всегда можем посчитать это вручную - но кто на самом деле это делает?
Изи

5

Python 2.x - 51

Та же концепция, что и у решения crazedgremlin для Python 3.x:

s=input();print s==sum(int(c)**len(`s`)for c in`s`)

4

C - 97 93 символа

a,b;main(c){scanf("%d",&c);b=c;for(;c;c/=10)a+=pow(c%10,(int)log10(b)+1);printf("%d",a==b);}

С отступом:

a,b;
main(c) { 
  scanf("%d",&c);
  b=c;
  for(;c;c/=10)
    a+=pow(c%10,(int)log10(b)+1);
  printf("%d",a==b);
}

2
Вам не нужно определять intглобальные переменные.
Конрад Боровски

Ого. Вы читаете вход в argc.
SIGSTACKFAULT

Кроме того, не должны ли делать -lmво время компиляции считать +1 байт?
SIGSTACKFAULT

@ Blacksilver -lmфлаг не требуется для компиляторов C89.
Джош

Ага. Узнай что-то новое каждый день.
SIGSTACKFAULT

4

Дельфы - 166

uses System.SysUtils,math;var i,r,l:integer;s:string;begin r:=0;readln(s);l:=length(s);for I:=1to l do r:=round(r+power(strtoint(s[i]),l));writeln(inttostr(r)=s);end.

С отступом

uses System.SysUtils,math;
var
  i,r,l:integer;
  s:string;
begin
  r:=0;
  readln(s);
  l:=length(s);
  for I:=1to l do
    r:=round(r+power(strtoint(s[i]),l));
  writeln(inttostr(r)=s);
end.



3

Awk: 40 39 символов

{for(;i<NF;)s+=$(i+++1)**NF;$0=$0==s}1

Образец прогона:

bash-4.1$ awk -F '' '{for(;i<NF;)s+=$(i+++1)**NF;$0=$0==s}1' <<< '153'
1

bash-4.1$ awk -F '' '{for(;i<NF;)s+=$(i+++1)**NF;$0=$0==s}1' <<< '1634'
1

bash-4.1$ awk -F '' '{for(;i<NF;)s+=$(i+++1)**NF;$0=$0==s}1' <<< '2013'
0

3

Баш, 64 символа

for((a=$1;a>0;s+=(a%10)**${#1},a/=10));do :; done;echo $[s==$1]

a = $ 1; p = $ {# a}; for ((; a> 0; a / = 10)); do s = $ ((s + (a% 10) ** p)); сделано; echo $ ( (ы == $ 1))


1
Вы используете переменную p в одном месте, поэтому в этом нет необходимости. Вы можете переместить инициализацию переменных А в forпощадить его обособленным ;: for((a=$1;a>0;a/=10));do s=$[s+(a%10)**${#1}];done;echo $[s==$1].
manatwork

1
Перемещая оценку в forеще один символ , может быть сокращено: for((a=$1;a>0;s+=(a%10)**${#1},a/=10));do :; done;echo $[s==$1].
manatwork

Ох, любопытно! Я попробовал что-то подобное, но это не сработало. Любопытно, что пошло не так.
пользователь неизвестен

3

Луа (101 символ)

Луа не известен своей краткостью, но в любом случае было интересно попробовать.

for n in io.lines()do l,s=n:len(),0 for i=1,l do d=n:byte(i)s=s+(d-48)^l end print(s==tonumber(n))end

Улучшения приветствуются.


Поскольку ваша программа не может обрабатывать и обрабатывать список чисел, я бы не использовал байты для реализации этой функциональности. Замена цикла for n in io.lines()do [...]endс n=io.read()экономит несколько байт ( TiO ).
Джонатан Фрех

3

JavaScript - 70 58 символов

for(i in a=b=prompt())b-=Math.pow(a[i],a.length)
alert(!b)

Примечание:

Если вы тестируете это в своей консоли разработчика в Stack Exchange, имейте в виду, что к String.prototypeэтому решению добавлено несколько нестандартных свойств , таких как String.prototype.formatUnicorn. Пожалуйста, не забудьте проверить в чистой среде, например, на about:blank.


Я насчитываю 70 символов там.
manatwork

@manatwork, упс, забыл сосчитать перевод строки.
zzzzBov

Отличный трюк с этим декрементом!
manatwork

2
это всегда возвращается trueдля меня, независимо от ввода
Коко

@koko, я добавил примечание, чтобы объяснить, почему вы получаете неправильные результаты.
zzzzBov

3

Java - 84 байта

(a,l)->{int s=0;for(byte c:a.getBytes())s+=Math.pow(c-48,l);return a.equals(""+s);};

Не лямбда-версия: 101 байт:

boolean n(String a,int l){int s=0;for(byte c:a.getBytes())s+=Math.pow(c-48,l);return a.equals(""+s);}

Вызывается так:

interface X {
    boolean n(String a, int l);
}

static X x = (a,l)->{int s=0;for(byte c:a.getBytes())s+=Math.pow(c-48,l);return a.equals(""+s);};

public static void main(String[] args) {
    System.out.println(n("153",3));
    System.out.println(n("1634",4));
    System.out.println(n("123",3));
    System.out.println(n("654",3));
}

Возвращает:

true
true
false
false

Вы можете убрать круглые скобки вокруг лямбда-аргументов, a,l->работает точно так же.
FlipTack

Я знаю, что вы отвечаете на это почти год назад, но вы можете (a,l)->a->l->byteinta->l->{int s=0;for(int c:a.getBytes())s+=Math.pow(c-48,l);return a.equals(""+s);}
Кевин Круйссен

3

Japt , 14 9 7 байт

¶ì_xpZÊ

Попробуйте онлайн


объяснение

Неявный ввод целого числа U.

ì_

Преобразовать Uв массив digits ( ì), передать его через функцию и затем преобразовать обратно в целое число.

xpZÊ

Уменьшите добавлением ( x), увеличивая каждый элемент до степени ( p) длины ( Ê) массива в процессе.

Проверьте, строго ли равен результат U.


Я думаю, что ¥U¬®n pUlÃxбудет работать на 11 байтов;)
Оливер


2

Общий Лисп - 116 102 персонажа

(defun f(m)(labels((l(n)(if(> n 0)(+(expt(mod n 10)(ceiling(log m 10)))(l(floor n 10)))0)))(= m(l m))))

отформатирован:

(defun f(m)
  (labels((l(n)
            (if(> n 0)
               (+(expt(mod n 10)(ceiling(log m 10)))
                 (l(floor n 10)))
               0)))
    (=(l m)m)))

2

Smalltalk - 102 99 символов

[:n|a:=n asString collect:[:e|e digitValue]as:Array.^n=(a collect:[:each|each raisedTo:a size])sum]

В рабочей области отправьте value:с номером и распечатайте его.


2

C #, 117

using System.Linq;class A{int Main(string[] a){return a[0].Select(c=>c-'0'^a[0].Length).Sum()==int.Parse(a[0])?1:0;}}

2

Haskell, 68 66 байт

d 0=[]
d n=mod n 10:d(div n 10)
sum.(\a->map(^length a)a).d>>=(==)

Использование:

*Main> sum.(\a->map(^length a)a).d>>=(==) $ 1634
True
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.