ทดสอบตัวเลขเพื่อหลงตัวเอง


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

ความท้าทาย:

รหัสของคุณจะต้องป้อนข้อมูลจากผู้ใช้และส่งออกจริงหรือเท็จขึ้นอยู่กับว่าหมายเลขที่กำหนดเป็นจำนวนหลงตัวเอง

การตรวจสอบข้อผิดพลาดสำหรับสตริงข้อความหรืออินพุตอื่นไม่ถูกต้อง 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)

ฉันใช้สองครั้งในการ `` ~. '' 'แต่ดูเหมือนว่าเป็นไปไม่ได้ที่จะปรับปรุง ทำได้ดีนี่.
Peter Taylor


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

การพูดอย่างเคร่งครัดถ้อยคำของข้อความท้าทายจะทำให้เกิดความคลุมเครือเล็กน้อยเกี่ยวกับความจริง / เท็จหรือ 0/1 ควรหมายความว่าดังนั้นฉันจะปล่อยให้สิ่งนี้ผ่านไป สคริปต์ที่แตกต่างกันที่มีความยาวเท่ากันซึ่งให้ผลตอบแทนจริงสำหรับค่าหลงตัวเองจะได้รับการพิจารณาเป็นพิเศษ
Iszi

แนวคิดเดียวกัน แต่สั้นกว่า:perl -pe'map$s+=$_**@y,@y=/./g;$_=$_==$s'
msh210

13

J, 23 ตัวอักษร

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

(1!:1)1 คืออินพุตคีย์บอร์ด (ส่งคืนสตริง)

".แปลงอินพุตเป็นตัวเลข "0ระบุอันดับ (ส่วนข้อมูล) เป็น 0 หรือกล่าวอีกนัยหนึ่งคือการใช้อักขระแต่ละตัวและแปลงเป็นตัวเลข

^คือฟังก์ชั่นพลังงานและ#เป็นฟังก์ชั่นความยาวจึงนำแต่ละหลักไปยังพลังของความยาวของสตริง (เทียบเท่าจำนวนของตัวเลข)

+/เป็นเพียงผลรวมและ=เปรียบเทียบผลรวมกับจำนวน


2
"รหัสของคุณจะต้องป้อนข้อมูลจากผู้ใช้และเอาท์พุทจริงหรือเท็จขึ้นอยู่กับว่าหมายเลขที่กำหนดเป็นจำนวนที่หลงตัวเอง" (เน้นที่เหมือง)
John Dvorak

@JanDvorak My bad - การเพิ่มคีย์บอร์ด
เหตุผล

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 (จำนวนอักขระที่aเป็น 3)
%%เป็น vectorized ดังนั้น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ที่เราและเมื่อเปรียบเทียบกับsuma


การหารจำนวนเต็มเสมอหรือไม่ มิฉะนั้นคุณอาจพบปัญหากับตัวอย่างเช่น 370 (หมายเลขหลงตัวเอง) เปลี่ยนเป็น 4,7,0 (ซึ่งจะคืนค่าเท็จ) หรือ 270 (ไม่ใช่ตัวตนหลงตัวเอง) เปลี่ยนเป็น 3,7,0 (คืนค่าจริง)
Iszi

การหารจำนวนเต็มไม่ปัด ... การหารจำนวนเต็ม 370 ด้วย 100 คือ 3 ด้วยส่วนที่เหลือ 70 และไม่ใช่ 3.70
plannapus

1
48 ไบต์ ... มีคนกดปุ่มนี้ในหน้าแรก!
Giuseppe

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ไม่มีฟังก์ชั่น
Ben

จุดดีแก้ไข
danmcardle

ฉันคิดว่าคุณควรชี้ให้เห็นว่าการเพิ่มการจัดฟันprint(ดังนั้นหนึ่งตัวอักษรมากขึ้น) จะทำให้การแก้ปัญหา Python 2.x และ Python 3.x ที่ถูกต้อง
Martin Thoma

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;สั้นกว่า
จัดการ

เนื่องจากคุณมีข้อความที่สร้างการแจ้งเตือนอยู่แล้วให้เพิ่มข้อความอื่น: เอาการเริ่มต้นตัวแปรการควบคุมแบบวนซ้ำ การเพิ่มตัวแปรควบคุมลูปไม่จำเป็นต้องเป็นคำสั่งแบบสแตนด์อะโลน <?for(;$i<$l=strlen($a=$argv[1]);)$s+=pow($a[$i++],$l);echo$s==$a;และวงเล็บจะแน่นอนไม่จำเป็นต้อง:
จัดการ

@ การทำงาน: ขอขอบคุณสำหรับการต้อนรับที่อบอุ่นกับ codegolf :)
Vlad Preda

สามารถเล่นกอล์ฟได้สิ่งนี้for(;$i<$l=strlen($a=$argn);)$s+=$a[$i++]**$l;echo$s==$a;
JörgHülsermann

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
Stan Strum


8

R, 53 ไบต์

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

gsubregex แทรกช่องว่างในระหว่างตัวอักษรเพื่อให้scanฟังก์ชั่นจะสามารถอ่านตัวเลขลงในเวกเตอร์ของตัวเลข


+1 ฉันไม่เคยคิดที่จะทำอย่างนั้นมันยอดเยี่ยม
plannapus


6

พาวเวอร์เซลล์, 75 63 62 60 58

แก้ไข: อัปเดตตามความคิดเห็นของ @ Iszi (หมายเหตุ: สิ่งนี้นับว่า$xไม่มีอยู่)

แก้ไข: เพิ่มการเปลี่ยนแปลงของ @ Danko แล้ว

[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 ก่อนที่ฉันจะทำ
Iszi

ประหยัด 12 ตัวโดยการเพิ่มตัวแปรอื่น$xและการใช้+=ที่จะทำข้อสรุปของคุณแทนการทดสอบแล้วmeasure -sum $x-eq$n
Iszi

1
61 chars:($x=$n=read-host)-split''|%{$x-=[math]::pow($_,$n.length)};!$x
Danko Durbić

1
@ DankoDurbić, Nice! การข่มขู่ประเภทมักจะมีประโยชน์กับการเล่นกอล์ฟรหัส PoSh ฉันได้ 62 เท่านั้นเมื่อฉันวิ่ง'($x=$n=read-host)-split""|%{$x-=[math]::pow($_,$n.length)};!$x'.length
Rynant

1
@ เรนท์จุดดี ฉันลองตรวจสอบความยาวของคุณใน PowerShell แล้วมาด้วย 62 ด้วย เมื่อใช้ระยะเวลาในการตรวจสอบในทำนองเดียวกันกับที่เกิดขึ้นจริงสคริปต์ก็ขึ้นมา 61 นี้น่าจะเป็นเพราะวิธีการ PowerShell จัดการที่คุณแทนที่ด้วย'' ''ฉันนำสคริปต์ต้นฉบับลงใน Excel เพื่อตรวจสอบอีกครั้ง=LEN("($x=$n=read-host)-split''|%{$x-=[math]::pow($_,$n.length)};!$x")และได้ 62 ด้วย แน่นอนเราสามารถนับมันได้ด้วยตนเอง - แต่ใครทำอย่างนั้นจริง ๆ
Iszi

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ตัวแปรส่วนกลาง
Konrad Borowski

ว้าว argcคุณกำลังอ่านใส่ลงใน
SIGSTACKFAULT

นอกจากนี้ไม่ควรทำ-lmที่นับเวลาคอมไพล์ด้วย +1 ไบต์?
SIGSTACKFAULT

@Blacksilver -lmไม่จำเป็นต้องใช้ธงสำหรับคอมไพเลอร์ C89
Josh

เอเอชเอ เรียนรู้สิ่งใหม่ทุกวัน
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

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

Bash, 64 ตัวอักษร

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

a = $ 1; p = $ {# a}; สำหรับ ((; a> 0; a / = 10)); do s = $ ((s + (a + 10%) ** p)); เสร็จแล้ว 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

Lua (101 ตัวอักษร)

Lua ไม่รู้จักกระชับ แต่ก็สนุกที่จะลอง

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 )
Jonathan Frech

3

JavaScript - 70 58 ตัวอักษร

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

บันทึก:

หากคุณกำลังทดสอบนี้ในคอนโซล dev ของคุณบนกองตลาดหลักทรัพย์ทราบว่ามีจำนวนของคุณสมบัติที่ไม่ได้มาตรฐานเพิ่มเพื่อที่จะทำลายการแก้ปัญหานี้เช่นString.prototype โปรดตรวจสอบในการทดสอบในสภาพแวดล้อมที่สะอาดเช่นบนString.prototype.formatUnicornabout:blank


ฉันนับ 70 ตัวอักษรที่นั่น
จัดการ

@ การจัดการการทำงานอ๊ะลืมที่จะนับบรรทัดใหม่
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->และbyteสามารถint:a->l->{int s=0;for(int c:a.getBytes())s+=Math.pow(c-48,l);return a.equals(""+s);}
Kevin Cruijssen

3

Japt , 14 9 7 ไบต์

¶ì_xpZÊ

ลองออนไลน์


คำอธิบาย

Uการป้อนข้อมูลโดยนัยของจำนวนเต็ม

ì_

แปลงUเป็นอาร์เรย์ของตัวเลข ( ì) ส่งผ่านฟังก์ชันและแปลงกลับเป็นจำนวนเต็มหลังจากนั้น

xpZÊ

ลดโดยการเพิ่ม ( x) โดยเพิ่มแต่ละองค์ประกอบเป็นกำลัง ( p) ของความยาว ( Ê) ของอาร์เรย์ในกระบวนการ

Uตรวจสอบว่าผลที่ได้คืออย่างเคร่งครัดเท่ากับ


ฉันคิดว่า¥U¬®n pUlÃxจะใช้งานได้ 11 ไบต์;)
Oliver


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

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.