Перевірте число на нарцисизм


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якщо істинно і 0якщо неправдиво.

Пояснення:

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

9
що я щойно прочитав
Jbwilliams1

4
@LagWagon Божа мова
tomsmeding

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.
манатура

Я думаю, що поки ви визначаєте, які ваші справжні та помилкові результати, це має бути законним
Cruncher

Власне кажучи, формулювання тексту виклику залишає певну неоднозначність щодо того, що має означати True / False або 0/1, тому я пропущу це. Перевага сценарію однакової довжини, яка повертає істинність для нарцисистських цінностей, хоч і матиме перевагу.
Іссі

Та ж ідея, але коротше: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 Моє погано - додано введення з клавіатури.
раціоналіс

12

Рубі, 34 + 5 = 39

З прапорами командного рядка

ruby -nlaF|

Біжи

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

Виходи істинні або помилкові.


3
Це, можливо, найбільше прапорів Ruby, які я коли-небудь бачив у законному гольф-коді: P
Doorknob

11

R, 71 69 66 56 48

Знижено на 8 байт завдяки @Giuseppe ! Ідея полягала у виконанні цілого поділу до операції модуля.

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

(Трирічна) стара версія з відповідним поясненням:

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

a<-scan()приймає число (ціле, дійсне, ...) як вхідне (скажімо 153для прикладу).
iстає вектором, що містить 3 до 1 (кількість символів aбуття 3).
%%"Векторизовано" 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 (що поверне помилкове) або 270 (ненарцистичне), перетворюючись на 3,7,0 (повернення істинного).
Іссі

Ділення цілого числа не округлює ... Ціле ділення 370 на 100 - це 3, а решта - 70, а не 3,70.
планнапус

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)
Мерінусом

Це круто! Дякую за пораду.
danmcardle

1
Ви можете зберегти два символи, видаливши пробіли в s = input()іншому та інший, перемістивши його на 2.7, де printце не функція.
Бен

Добрий момент, відредаговано.
danmcardle

Я думаю, вам слід зазначити, що додавання дужок до 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.

Thx @manatwork для скорочення багатьох символів.


Не призначайте $ a та $ l в окремих операторах. <?for($i=0;$i<$l=strlen($a=$argv[1]);$i++){$s+=pow($a[$i],$l);}echo$s==$a;коротше.
манатура

Оскільки ви вже маєте заяву, яка генерує повідомлення, просто додайте інше: видаліть ініціалізацію змінної керування циклом. Збільшення змінної керування циклом також не повинно бути окремим твердженням. І брекети, безумовно , не потрібно: <?for(;$i<$l=strlen($a=$argv[1]);)$s+=pow($a[$i++],$l);echo$s==$a;.
манатура

@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 char із перепорядкуванням

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

8

R, 53 байти

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

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


+1 я б ніколи не думав цього робити, це геніально.
планнапус


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
Рінант

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

Delphi - 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

Haskell 2010 - 76 символів

main=do x<-getLine;print$(==x)$show$sum$map((^length x).(+(-48)).fromEnum)x

1
Ви не повинні розміщувати кількість мс для запуску коду, а кількість знаків, які ви використовували. ;)
користувач невідомий

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)); done; echo $ ( (s == $ 1))


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

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

О, цікаво! Я спробував щось подібне, але не вийшло. Цікаво, що пішло не так.
користувач невідомий

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, ну, забув порахувати новий рядок.
zzzzBov

Чудовий трюк, що декрементація!
манатурка

2
це завжди повертається trueдля мене, незалежно від вкладу
koko

@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на масив цифр ( ì), передати його через функцію та перетворити назад у ціле число після.

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

Маленька розмова - 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.