Kiểm tra một số cho lòng tự ái


53

Một số tự mãn là một số trong đó là tổng các chữ số của riêng mình, mỗi lũy thừa của số chữ số.

Ví dụ: lấy 153 (3 chữ số):

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

1634:

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

Các thách thức:

Mã của bạn phải lấy đầu vào từ người dùng và đầu ra Đúng hay Sai tùy thuộc vào số đã cho có phải là Số Narcissistic hay không.

Lỗi kiểm tra các chuỗi văn bản hoặc các đầu vào không hợp lệ khác là không bắt buộc. 1 hoặc 0 cho đầu ra là chấp nhận được. Mã chỉ đơn giản là tạo danh sách Số Narcissistic hoặc kiểm tra đầu vào của người dùng đối với danh sách, không đủ điều kiện.

OEIS A005188


3
Có ổn không nếu tôi xuất ra Truenếu đó là một số như vậy, nhưng bất cứ điều gì khác (trong trường hợp này là số đó) nếu không?
devR Rich

Câu trả lời:


39

APL (15)

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

Đầu ra 1nếu đúng và 0nếu sai.

Giải trình:

  • ∆←⍞: đọc một dòng (dưới dạng ký tự), lưu trữ trong
  • (⍎¨∆)*⍴∆: đánh giá từng nhân vật và nâng nó lên thành sức mạnh⍴∆
  • ∆≡⍕+/: xem liệu đầu vào có bằng biểu diễn chuỗi của tổng của các giá trị này không

9
tôi vừa đọc gì
Jbwilliams1

4
@LagWagon Ngôn ngữ của Chúa
tomsmeding

21

GolfScript, 16 ký tự

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

Đầu vào phải được đưa ra trên STDIN, đầu ra là 0 hoặc 1 cho biết số không tự ái / tự ái.

Giải thích về mã:

~              # 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)

Tôi đã thực hiện gấp đôi `` ~ .` `` nhưng dường như không thể cải thiện. Đẹp một.
Peter Taylor

15

Toán học, 43 ký tự

Tr[#^Length@#&@IntegerDigits@#]==#&@Input[]

14

Perl, 38 ký tự

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

Một cách thực hiện khá đơn giản.

Đây là một phiên bản hơi khác nhau, phù hợp với 35 ký tự:

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

Phiên bản này xuất ra một giá trị sai nếu đầu vào là tự ái, nếu không, nó tạo ra giá trị đúng (được chấp nhận). Người ta có thể lập luận rằng phiên bản ngược này nằm trong giới hạn của mô tả thử thách, nhưng theo phản ánh tôi đã quyết định không. Tôi không tuyệt vọng để cải thiện điểm số của mình. Chưa.


Lỗi kiểm tra lỗi cho chuỗi văn bản hoặc các đầu vào không hợp lệ khác là không bắt buộc. Vì vậy, tại sao không giả sử đầu vào sẽ là số hợp lệ, mà không theo dõi dòng mới? echo -n 153 | perl -pe '…'sẽ làm việc mà không có -l.
manatwork

Tôi nghĩ miễn là bạn xác định đầu ra đúng và sai của mình là gì thì nó phải hợp pháp
Cruncher

Nói một cách chính xác, từ ngữ của văn bản thách thức sẽ để lại một chút mơ hồ về ý nghĩa của Đúng / Sai hoặc 0/1, vì vậy tôi sẽ để điều này vượt qua. Mặc dù vậy, một tập lệnh khác có độ dài bằng nhau trả về giá trị đúng cho các giá trị tự sự sẽ có lợi thế.
Iszi

Cùng một ý tưởng nhưng ngắn hơn:perl -pe'map$s+=$_**@y,@y=/./g;$_=$_==$s'
msh210

13

J, 23 ký tự

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

(1!:1)1 là đầu vào bàn phím (trả về một chuỗi).

".chuyển đổi đầu vào thành một số; "0chỉ định thứ hạng (thứ nguyên) là 0, nói cách khác, lấy từng ký tự và chuyển đổi nó thành một số.

^là hàm lũy thừa và #là hàm độ dài, do đó lấy mỗi chữ số thành lũy thừa của độ dài của chuỗi (tương đương với số chữ số).

+/chỉ là tổng, và =đang so sánh tổng và số.


2
"Mã của bạn phải lấy đầu vào từ người dùng và đầu ra Đúng hay Sai tùy thuộc vào việc số đã cho có phải là Số Narcissistic hay không." (nhấn mạnh của tôi)
John Dvorak

@JanDvorak Tôi xấu - thêm đầu vào bàn phím.
rationalis

12

Hồng ngọc, 34 + 5 = 39

Với cờ dòng lệnh

ruby -nlaF|

Chạy

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

Đầu ra đúng hoặc sai.


3
Đây có thể là những lá cờ Ruby nhất mà tôi từng thấy trong một mã golf hợp pháp: P
Doorknob

11

R, 71 69 66 56 48

Giảm 8 byte nhờ @Giuseppe ! Ý tưởng là để thực hiện phân chia số nguyên trước khi hoạt động modulo.

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

(3 năm) phiên bản cũ với lời giải thích tương ứng:

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

a<-scan()lấy một số (số nguyên, số thực, ...) làm đầu vào ( 153ví dụ: ví dụ).
itrở thành một vectơ chứa 3 đến 1 (số ký tự alà 3).
%%được vector hóa vì vậy a%%10^icó nghĩa là amodulo 1000, 100 và 10: do đó nó mang lại 153, 53, 3.
(a%%10^i)%/%10^(i-1)là phép chia số nguyên của vectơ đó theo 100, 10, 1: do đó , 1, 5, 3.
Chúng tôi nâng cao điều đó với phần tử đầu tiên của ilà số ký tự (ở đây chữ số) của a, ví dụ 3, do đó đem lại một vector chứa 1, 125, 27mà chúng tôi sumvà so sánh với a.


Phân chia số nguyên luôn làm tròn xuống? Mặt khác, bạn có thể gặp vấn đề với ví dụ: 370 (số tự ái) biến thành 4,7,0 (sẽ trả về sai) hoặc 270 (không tự ái) biến thành 3,7,0 (trả lại đúng).
Iszi

Phép chia số nguyên không làm tròn ... Phép chia số nguyên của 370 cho 100 là 3 với phần còn lại là 70 và không phải là 3,70.
plannapus

1
48 byte ... ai đó đã gửi nó đến trang chủ!
Giuseppe

9

Python 3, 56 byte

Không khó hiểu lắm, nhưng là một giải pháp đơn giản.

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

1
Các []là không cần thiết, và bạn có thể thả không gian ở phía trước forquá, vì vậy:sum(int(c)**len(s)for c in s)
marinus

Thật tuyệt vời! Cảm ơn vì tiền hỗ trợ.
danmcardle

1
Bạn có thể lưu hai ký tự bằng cách xóa khoảng trắng trong s = input()và một ký tự khác bằng cách di chuyển ký tự này sang 2.7 trong đó printkhông phải là hàm.
Ben

Điểm tốt, chỉnh sửa.
danmcardle

Tôi nghĩ bạn nên chỉ ra rằng việc thêm dấu ngoặc vào print(do đó thêm một ký tự) sẽ làm cho điều này trở thành một giải pháp Python 2.x và Python 3.x hợp lệ.
Martin Thoma

8

PHP, 80 74 66 ký tự

Giải pháp PHP rất đơn giản:

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

Nó giả định error_reportingkhông bao gồm các thông báo, nếu không sẽ cần thêm một vài ký tự để khởi tạo $s=0;$i=0.

Thx @manatwork để rút ngắn nhiều ký tự.


Đừng gán $ a và $ l trong các câu lệnh riêng biệt. <?for($i=0;$i<$l=strlen($a=$argv[1]);$i++){$s+=pow($a[$i],$l);}echo$s==$a;ngắn hơn
manatwork

Khi bạn đã có một câu lệnh tạo thông báo, chỉ cần thêm một câu lệnh: loại bỏ khởi tạo biến điều khiển vòng lặp. Tăng biến điều khiển vòng lặp cũng không cần phải là một câu lệnh độc lập. Và niềng răng chắc chắn là không cần thiết : <?for(;$i<$l=strlen($a=$argv[1]);)$s+=pow($a[$i++],$l);echo$s==$a;.
manatwork

@manatwork: Cảm ơn bạn đã chào đón nồng nhiệt đến codegolf :)
Vlad Preda

Có thể chơi gôn nàyfor(;$i<$l=strlen($a=$argn);)$s+=$a[$i++]**$l;echo$s==$a;
Jörg Hülsermann

8

Đc: 48 ký tự

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

Chạy mẫu:

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

Không bao giờ thực sự được sử dụng dc, tiết kiệm cho các lỗi chính tả điên cuồng trong nỗ lực viếtcd
Stan Strum

8

K, 24 23

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

Cạo 1 char với sắp xếp lại

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

8

R, 53 byte

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

Các gsubregex chèn khoảng trống ở giữa các nhân vật, do đó scanchức năng sẽ có thể đọc các số vào một vector của các chữ số.


+1 tôi sẽ không bao giờ nghĩ làm điều đó, nó thật tuyệt vời.
plannapus


6

Quyền hạn, 75 63 62 60 58

Chỉnh sửa: Đã cập nhật nhận xét của mỗi @ Iszi (lưu ý: điều này được tính là $xkhông tồn tại)

Chỉnh sửa: Đã thêm @ Danko thay đổi.

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

58 56 ký tự

Nếu đầu vào bị giới hạn ở 10 chữ số (bao gồm tất cả int32)

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

Tôi đã tự hỏi nếu ai đó sẽ làm PowerShell trước khi tôi làm.
Iszi

Lưu 12 ký tự bằng cách thêm một biến khác $xvà sử dụng +=để thực hiện tổng kết của bạn thay vì measure -sumsau đó kiểm tra $x-eq$n.
Iszi

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

1
@ DankoDurbić, tốt đẹp! Kiểu ép buộc thường có ích với việc đánh gôn bằng mã PoSh. Tôi chỉ nhận được 62 mặc dù khi tôi chạy'($x=$n=read-host)-split""|%{$x-=[math]::pow($_,$n.length)};!$x'.length
Rynant

1
@Rynant Điểm tốt. Tôi đã chạy kiểm tra độ dài của bạn trong PowerShell và cũng đã đưa ra 62. Khi chạy kiểm tra độ dài tương tự với tập lệnh thực tế , nó xuất hiện 61. Điều này có thể là do cách PowerShell xử lý cái ''mà bạn đã thay thế ''. Tôi lấy kịch bản gốc vào Excel để kiểm tra lại =LEN("($x=$n=read-host)-split''|%{$x-=[math]::pow($_,$n.length)};!$x")và nhận được 62. Tất nhiên, chúng ta luôn có thể đếm nó bằng tay - nhưng ai thực sự làm điều đó?
Iszi

5

Con trăn 2.x - 51

Khái niệm tương tự như giải pháp của crazinggremlin cho Python 3.x:

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

4

C - 97 93 ký tự

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

Với vết lõm:

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
Bạn không phải xác định intcho các biến toàn cục.
Konrad Borowski

Ái chà. Bạn đang đọc đầu vào argc.
SIGSTACKFAULT

Ngoài ra, không nên thực hiện -lmở thời gian biên dịch +1 byte?
SIGSTACKFAULT

@Blacksilver -lmkhông yêu cầu cờ cho trình biên dịch C89.
Josh

Aha. Học một điều mới mỗi ngày.
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.

Với thụt lề

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 ký tự

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

Chạy mẫu:

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 ký tự

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


1
Bạn đang sử dụng biến p ở một nơi duy nhất, vì vậy không cần nó. Bạn có thể di chuyển việc khởi tạo biến a thành forphụ tùng riêng của nó ;: for((a=$1;a>0;a/=10));do s=$[s+(a%10)**${#1}];done;echo $[s==$1].
manatwork

1
Bằng cách di chuyển đánh giá vào formột ký tự nữa có thể được rút ngắn : for((a=$1;a>0;s+=(a%10)**${#1},a/=10));do :; done;echo $[s==$1].
manatwork

Ôi, tò mò quá! Tôi đã thử một cái gì đó như thế, nhưng nó không hoạt động. Tò mò chuyện gì đã xảy ra.
người dùng không xác định

3

Lua (101 ký tự)

Lua không được biết đến là súc tích, nhưng dù sao cũng rất vui khi thử.

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

Cải tiến chào mừng.


Vì không bắt buộc chương trình của bạn có thể xử lý và xử lý danh sách các số, tôi sẽ không sử dụng byte để thực hiện chức năng đó. Thay thế vòng lặp for n in io.lines()do [...]endbằng cách n=io.read()lưu một số byte ( TIO ).
Jonathan Frech

3

JavaScript - 70 58 ký tự

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

Ghi chú:

Nếu bạn đang kiểm tra điều này trong bảng điều khiển dành cho nhà phát triển của mình trên Stack Exchange, hãy lưu ý rằng có một số thuộc tính không chuẩn được thêm vào String.prototypesẽ phá vỡ giải pháp này, chẳng hạn như String.prototype.formatUnicorn. Hãy chắc chắn để kiểm tra trong một môi trường sạch sẽ, chẳng hạn như trên about:blank.


Tôi đếm 70 ký tự ở đó.
manatwork 15/11/13

@manatwork, rất tiếc, quên đếm dòng mới.
zzzzBov

Bí quyết lớn mà giảm!
manatwork 16/11/13

2
nó luôn trả về truecho tôi, bất kể đầu vào
koko

@koko, tôi đã thêm một ghi chú để giải thích lý do tại sao bạn nhận được kết quả không chính xác.
zzzzBov

3

Java - 84 byte

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

Phiên bản không phải lambda: 101 byte:

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

Được gọi như thế này:

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

Trả về:

true
true
false
false

Bạn có thể loại bỏ dấu ngoặc quanh các đối số lambda, a,l->hoạt động chính xác như nhau.
FlipTack

Tôi biết bạn đã trả lời câu hỏi này gần một năm trước, nhưng bạn có thể chơi hai byte: (a,l)->có thể a->l->bytecó thể 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 byte

¶ì_xpZÊ

Dùng thử trực tuyến


Giải trình

Đầu vào ngầm định của số nguyên U.

ì_

Chuyển đổi Uthành một mảng các chữ số ( ì), chuyển nó qua một hàm và chuyển đổi trở lại một số nguyên sau.

xpZÊ

Giảm bằng phép cộng ( x), nâng từng phần tử lên lũy thừa ( p) của độ dài ( Ê) của mảng trong quy trình.

Kiểm tra nếu kết quả hoàn toàn bằng U.


Tôi nghĩ rằng ¥U¬®n pUlÃxsẽ làm việc cho 11 byte;)
Oliver

2

F # - 92 ký tự

let n=stdin.ReadLine()
n|>Seq.map(fun x->pown(int x-48)n.Length)|>Seq.sum=int n|>printf"%b"

2

Lisp chung - 116 102 ký tự

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

Định dạng:

(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 ký tự

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

Tại Workspace, gửi value:với số và In.


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 byte

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

Sử dụng:

*Main> sum.(\a->map(^length a)a).d>>=(==) $ 1634
True
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.