ตัวเลขหารด้วยตัวเลขแต่ละตัวหรือไม่


47

เพื่อนของฉันและฉันกำลังทำงานในห้องแล็บในวิชาวิทยาศาสตร์คอมพิวเตอร์ AP ของเราและตัดสินใจที่จะเขียนรหัสกอล์ฟปัญหาเนื่องจากเรายังมีครึ่งชั้นเรียนฟรีหลังจากเสร็จ นี่คือคำถาม:

รับตัวเลข n, หารด้วยตัวเลขแต่ละตัวได้หรือไม่?

ตัวอย่างเช่น 128 จะผ่านการทดสอบนี้มันหารด้วย 1,2 และ 8 ตัวเลขใด ๆ ที่มีศูนย์จะตัดสิทธิ์หมายเลขนั้นโดยอัตโนมัติ ในขณะที่คุณอาจใช้ภาษาอื่นและโพสต์โซลูชันด้วยหากต้องการเรามีความสนใจมากที่สุดในการเห็นว่าผู้ใช้งานขนาดเล็กสามารถสร้างโปรแกรมใน Java ได้อย่างไรเนื่องจากเป็นภาษาที่เราใช้ในชั้นเรียน จนถึงตอนนี้เราทั้งคู่มี 51 นี่คือรหัสปัจจุบันของฉัน:

public boolean dividesSelf(int n){for(int p=n;n%10>0;)n/=p%(n%10)>0?.1:10;return n<1;}
// 51 characters

// Breakdown:
// for(int p=n;         Saves one semicolon to put declaration into for loop
// n%10>0;)             Basic check-for-zero
// n/=                  Pretty simple, discarding one number off of n at a time
// p%(n%10)>0?          If p (the given value) is not divisible by n%10 (the current digit)...
// .1:10;               Divide by .1 (multiply by 10) so it fails the check next iteration. If it is divisible, divide by 10 to truncate the last digit
// return n<1           If the number was fully divisible, every digit would be truncated, and n would be 0. Else, there would still be non-zero digits.

ความต้องการ

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

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

128 -> true
 12 -> true
120 -> false
122 -> true
 13 -> false
 32 -> false
 22 -> true
 42 -> false
212 -> true
213 -> false
162 -> true
204 -> false

นอกจากนี้เราไม่ได้นับช่องว่างดังนั้นอย่าลังเลที่จะทำเช่นเดียวกันเว้นแต่ช่องว่างนั้นมีความสำคัญต่อการทำงานของโปรแกรม (ดังนั้นการขึ้นบรรทัดใหม่ใน Java จะไม่นับ แต่เว้นวรรคเดียวระหว่างintและx=1นับ) โชคดี !


18
ยินดีต้อนรับสู่ PPCG! คำแนะนำเล็กน้อย: 1. การนับพื้นที่ว่างในการทำงานนับเป็นความคิดที่ไม่ดี คำตอบใด ๆ ที่เขียนในWhitespaceจะชนะโดยอัตโนมัติ 2. ผลงานพิมพ์ของเราควรพิมพ์ / ส่งคืนtrueและfalseหรือเป็นจริง /ค่าเท็จตกลงเช่นกัน? 3. javaแท็กไม่ได้ใช้ที่นี่เนื่องจากความท้าทายนั้นไม่เกี่ยวข้องกับ Java
เดนนิส

ถูก ขอโทษสำหรับปัญหา คุณต้องการพิจารณาพื้นที่ใน 'int p = n' เพื่อใช้งานได้หรือไม่เพราะฉันไม่ได้ก่อนหน้านี้ ฉันจะแก้ไขปัญหาอื่น ๆ ที่คุณชี้ให้เห็น
Mathew Kirschbaum

5
ช่องว่างทั้งหมดที่จำเป็นสำหรับรหัสในการทำงานนั้นทำงานได้
FryAmTheEggman

โอเคขอบคุณสำหรับคำตอบ!
Mathew Kirschbaum

1
@RickyDemer: เนื่องจาก 0 จะเป็นข้อมูลที่ยอดเยี่ยมในกรณีนั้น (เป็นตัวเลขเดียวที่มี0ตัวเลขที่เป็นจำนวนมากของแต่ละคน) ฉันคิดว่าคำตอบส่วนใหญ่จะได้นานขึ้นในวิธีที่ไม่น่าสนใจที่จะรวมการตรวจสอบ ดังนั้นฉันจึงชอบปัญหาที่เกิดขึ้นจากชื่อเรื่องนั้นดีกว่า (หารด้วยตัวเลขแทนที่จะเป็นตัวเลขหลายหลักซึ่งไม่รวม 0)
Jeroen Mostert

คำตอบ:


23

Perl 6, 13

sub golf($_) {
   $_%%.comb.all
}

ใช้ตัวแปรนัย$_- เทียบเท่ากับ$_ %% .comb.all คือโอเปอเรเตอร์ "is หารได้" และไม่มีอาร์กิวเมนต์เพิ่มเติมส่งคืนรายการของอักขระในสตริง ตัวอย่างเช่นถ้าอาร์กิวเมนต์เป็น 123 ฟังก์ชันจะประเมินค่า$_ %% all($_.comb)%%comb

123 %% all(123.comb)

ซึ่งเป็น

123 %% all(1, 2, 3)

การแยกอัตโนมัติทำให้มัน

all(123 %% 1, 123 %% 2, 123 %% 3)

ซึ่งเป็น

all(True, False, True)

ซึ่งเป็นเท็จในบริบทบูลีนเพราะมันเป็นชุมทาง "ทั้งหมด" และชัดเจนว่าองค์ประกอบทั้งหมดไม่เป็นความจริง

มันเป็นไปได้ที่จะบีบบังคับค่าที่ส่งคืนไปยังBoolและซ่อน junction-ness จากผู้โทรโดยการทำให้ฟังก์ชั่นลายเซ็นsub golf($_ --> Bool())แต่ coercions ในฟังก์ชั่นลายเซ็นยังไม่ทำงานใน Rakudo ค่าตอบแทนยังคงถูกต้องจริงหรือเท็จก็แค่ไม่ได้หรือTrueFalse


หากคุณต้องการที่จะให้มันกลับมาเป็นBoolเพียงแค่เพิ่มไปยังด้านหน้าของรหัสso so$_%%.comb.all
Brad Gilbert b2gills

21

C # และ System.Linq - 26/40

ตามกฎที่ไม่นับการประกาศวิธีการเอง

bool dividesSelf(int i) { 
    return(i+"").All(d=>i%(d-48d)<1);
}

แสดงให้เห็นว่าอีกครั้ง C # เป็นตัวเลือกที่ยอดเยี่ยมเมื่อ Java อยู่ในระหว่างการพิจารณา ... I kid, I kid!

น่าเสียดายที่ฟังก์ชั่นนี้ (และคำตอบอื่น ๆ อีกมากมาย) จะไม่ให้ผลลัพธ์ที่ถูกต้องสำหรับการป้อนข้อมูลเชิงลบ เราสามารถแก้ไขปัญหานี้ได้ แต่โซลูชันสูญเสียเสน่ห์มากมาย (และเพิ่มความยาวได้ถึง 46 อักขระ):

return(i+"").All(d=>d>48&&i%(d-48)==0||d==45);

แก้ไข : โกนอักขระหนึ่งตัวพร้อมคำแนะนำของ Tim

แก้ไข : ด้วยการแนะนำของสมาชิกที่มีการแสดงออกใน C # 6 เราสามารถตัดสิ่งนี้ออกไปได้อีกโดยตัดสิ่งต่อไปนี้ออกreturn:

bool dividesSelf(int i) =>
    (i+"").All(d=>i%(d-48d)<1);

สำหรับทั้งหมด 26 ตัวอักษร (ในความคิดของฉัน=>ไม่ควรรวมมากกว่าการจัดฟัน) เวอร์ชันการจัดการตัวเลขติดลบสามารถทำให้สั้นลงได้ในทำนองเดียวกัน


ทำไม.0? ไม่จำเป็นต้องมีอะไรนอกจากโมดูลัสจำนวนเต็ม
Peter Taylor

3
@PeterTaylor: มีคือถ้าคุณต้องการให้โปรแกรมสั้น - i % 0มีจำนวนเต็มให้i DivideByZeroException
Jeroen Mostert

2
และด้วย double มันให้ NaN! ดี!
Peter Taylor

2
48dเหมือนกัน48.0แต่มีอักขระน้อยกว่าหนึ่งตัว (d สำหรับสองเท่า)
ทิมเอส

1
@StartLC: lambdas ไม่ใช่วิธีการ ขอบเขตของพวกเขานั้นแตกต่างกันดังนั้นฉันคิดว่ามันก้มกฏมากเกินไป แต่เนื่องจาก C # 6 (ซึ่งคำตอบนี้มาก่อน) เรามีสมาชิกที่มีร่างกายที่แสดงออกซึ่งทำให้เราสามารถทำให้คำจำกัดความสั้นลงได้ สำหรับกรณีเชิงลบเราไม่สามารถใช้งาน&ได้อย่างแม่นยำเพราะ&ไม่ลัดวงจร - %คุณจะได้รับการหารด้วยศูนย์ข้อยกเว้นใน เราสามารถแก้ไขได้โดยทำให้เป็นสองเท่า (ด้วยd) แต่จากนั้นเราได้สูญเสียอักขระหนึ่งตัวอีกครั้ง
Jeroen Mostert

18

APL ( 13 11)

(เห็นได้ชัดว่าวงเล็บไม่นับ)

{0∧.=⍵|⍨⍎¨⍕⍵}

คำอธิบาย:

  • ⍎¨⍕⍵: ประเมินอักขระแต่ละตัวในการแทนค่าสตริงของ
  • ⍵|⍨: สำหรับแต่ละคนค้นหาโมดูโลของมันและ
  • 0∧.=: ดูว่าทั้งหมดเหล่านี้เท่ากับ 0

Testcases:

      N,[.5] {0∧.=⍵|⍨⍎¨⍕⍵} ¨ N←128 12 120 122 13 32 22 42 212 213 162 204
128 12 120 122 13 32 22 42 212 213 162 204
  1  1   0   1  0  0  1  0   1   0   1   0

APL สามารถทำX%0อะไรได้บ้าง โดยไม่ต้องขว้างปา?
เครื่องมือเพิ่มประสิทธิภาพ

@Optimizer: ใช่ จะช่วยให้0|X X
marinus

หวาน. คำตอบของคุณคือ 11 ไบต์ไม่ใช่ 13
เครื่องมือเพิ่มประสิทธิภาพ

9
เพียง APL จะไม่ให้เกิดข้อผิดพลาดในแบบโมดูโลจาก 0, และความผิดพลาดในการประเมินไม่ใช่บูลบูลเป็นหนึ่ง)
FryAmTheEggman

3
ตัวละครตัวหนึ่งสั้นลงด้วยรถไฟแทน dfn:(0∧.=⍎¨∘⍕|⊢)
ngn

14

Python 2: 43 ตัวอักษร

f=lambda n:any(n%(int(d)or.3)for d in`n`)<1

ตรวจสอบว่าจำนวนที่เหลืออยู่ใด ๆ ที่ไม่ใช่ศูนย์โมดูโลตัวเลขและส่งกลับการปฏิเสธของที่ เลขศูนย์ถูกจัดการอย่างประหลาด: เนื่องจากการคำนวณ%0ทำให้เกิดข้อผิดพลาดตัวเลขของ0จะถูกแทนที่ด้วย.3ซึ่งดูเหมือนจะให้ผลลัพธ์ที่ไม่ใช่ศูนย์เสมอเนื่องจากความไม่ถูกต้องของจุดลอย

ฟังก์ชั่นร่างกายเป็น 32 ตัวอักษร


14

Perl - 27 ไบต์

sub dividesSelf{
    $_=pop;s/./!$&||$_%$&/ger<1
}

ไม่นับลายเซ็นฟังก์ชั่นตามคำสั่ง

ตัวอย่างการใช้งาน:

use Data::Dump qw(dump);
for $i (128, 12, 120, 122, 13, 32, 22, 42, 212, 213, 162, 204) {
  printf "%3d -> %s\n", $i, dump(dividesSelf $i);
}

ตัวอย่างผลลัพธ์:

128 -> 1
 12 -> 1
120 -> ""
122 -> 1
 13 -> ""
 32 -> ""
 22 -> 1
 42 -> ""
212 -> 1
213 -> ""
162 -> 1
204 -> ""

การระบุถึงข้อมูลจำเพาะของปัญหา: "นับเฉพาะค่าบูลีนจริงและเท็จเท่านั้นนับค่า Truthy / falsey ไม่นับ"

use Data::Dump qw(dump);
dump(1 == 1);
dump(0 == 1);

ขาออก:

1
""

'ทรู' และ 'เท็จ' จะถูกกำหนดเป็นและ1""

Erratum:
แบรดกิลเบิร์ตชี้ให้เห็นอย่างถูกต้อง Perl กำหนดความจริงเป็นสเกลาร์ซึ่งเป็นทั้งจำนวนเต็ม1และสตริง"1"พร้อมกันและเท็จเป็นสเกลาร์ซึ่งเป็นทั้งจำนวนเต็ม0และสตริง""พร้อมกัน


สิ่งนี้สามารถสั้นลงได้โดยไม่ใช้$_: pop=~s///ger<1. ฉันไม่รู้ว่า OP จะยอมรับหรือไม่1และ""เป็นผลลัพธ์ที่ถูกต้อง ถ้าไม่ได้แล้วมันสามารถแก้ไขด้วยไบต์ที่สองเพิ่มเติมได้ที่: |0เพียงแค่เพิ่ม
hvd

perl -pe'$_=s/./!$&||$_%$&/ger<1|0'คือ 26 ไบต์ซึ่งรวมถึง|0และ-pแฟล็ก คุณไม่จำเป็นต้องใช้ฟังก์ชั่น
hmatt1

1
ที่จริงทรูและเท็จค่ามีมากขึ้นเช่นและdualvar(1,'1') dualvar(0,'')
Brad Gilbert b2gills

1
@BradGilbert นั่นน่าสนใจ ฉันคุ้นเคยกับ perlguts พอสมควร แต่ฉันไม่รู้ว่าจริงและเท็จเป็นกรณีพิเศษ จริงๆแล้วพวกมันคือ 'สามสเกลาร์ส', ทำเครื่องหมายเป็นSVIV(int), SVNV(สองครั้ง) และSVPV(สตริง)
โม่

1
จริงๆแล้วครั้งแรกที่คุณใช้สตริงเป็นตัวเลขหรือตัวเลขเป็นสตริงตัวแปรจะถูกปรับเปลี่ยนเพื่อเก็บข้อมูลเพิ่มเติมนั้นไว้ นั่นคือเหตุผลที่คุณจะได้รับการเตือนในครั้งแรกที่คุณใช้'abc'เป็นตัวเลขเท่านั้น (สมมติว่าคุณuse warnings;เปิดใช้งานไว้)
Brad Gilbert b2gills

13

CJam, 11 10 ไบต์

{
    _Ab:df%:+!
}:F;

สิ่งนี้กำหนดฟังก์ชั่นที่มีชื่อFและทิ้งบล็อกจากสแต็ค

ลองออนไลน์

กรณีทดสอบ

$ cjam <(echo '{_Ab:df%:+!}:F;[128 12 120 122 13 32 22 42 212 213 162 204]{F}%p')
[1 1 0 1 0 0 1 0 1 0 1 0]

มันทำงานอย่างไร

_      " Copy the integer on the stack.                                          ";
Ab     " Push the array of its digits in base 10.                                ";
:d     " Cast each digit to Double.                                              ";
f%     " Take the integer on the stack modulus each of its digits.               ";
:+     " Add the results.                                                        ";
!      " Push the logical NOT of the sum.                                        ";

CJam มีคุณสมบัติที่คุณใช้สำหรับการแก้ปัญหา 10 ไบต์เมื่อเขียนคำถามหรือไม่
lirtosiast

@ThomasKwa: ใช่แล้ว ฉันทดสอบโค้ดในเวอร์ชัน 0.6.2 ซึ่งวางจำหน่ายในเดือนกรกฎาคม 2014
Dennis

12

JavaScript ES6, 39 32 28 ไบต์

v=>[...""+v].every(x=>v%x<1)

ขอบคุณ core1024 สำหรับคำแนะนำเพื่อแทนที่(""+v).split("")ด้วย[...""+v]และ openorclose สำหรับการแนะนำการใช้everyฟังก์ชั่น

คำตอบปัจจุบันไม่มีรหัสของฉันหนึ่งบิต: O

วิธีแก้ไขก่อนหน้า

v=>[...""+v].filter(x=>v%x|!+x)==""

==""ไม่ใช่วิธีที่ถูกต้องในการตรวจสอบว่าอาร์เรย์ว่างเปล่าหรือไม่เนื่องจาก[""]==""ส่งคืนtrueแต่อาร์เรย์รับประกันว่าจะมีสตริงที่ไม่ว่างดังนั้นจึงทำงานได้ที่นี่

ส่วนที่เหลือเป็นการแปลงชวเลขชนิดมาตรฐานใน JavaScript


1
คุณสามารถบันทึก characteras บางโดยการแทนที่ด้วย(""+v).split("") [...""+v]
core1024

1
ทำไมไม่ใช้everyวิธีการ? v=>[...""+v].every(x=>v%x<1);
openorclose

@openorclose: ขอบคุณ ไม่เคยมีโอกาสใช้มันใน JS ดังนั้นฉันไม่เคยคิดถึงการค้นหาฟังก์ชั่นดังกล่าว
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

v=>![...""+v].some(x=>v%x)
l4m2

@ l4m2 เนื่องจากv%0ผลตอบแทนNaNและNaN == falseดังนั้นในกรณีที่ตัวเลขของคุณที่มี 0 เช่นอาจกลับ10 true
Shieru Asakoto

9

Java 8, 46 Bytes (ส่วนของเมธอด)

ใช้Jeroen Mostertแปลงเป็นเคล็ดลับสองเท่า

public static boolean dividesSelf(int n) {
    return(""+n).chars().allMatch(x->n%(x-48d)<1);
}

8

Pyth, 12 ไบต์

!f|!vT%vzvTz

สิ่งนี้จะกรองอักขระในสตริงเพื่อให้เป็นศูนย์ ( !vT) หรือไม่หารอินพุต ( %vzvT) จากนั้นใช้ตรรกะที่ไม่อยู่ในรายการผลลัพธ์

ลองที่นี่


ไม่ฉันไม่เป็นไรถ้าฟังก์ชั่นไม่ได้ใช้ ฉันแค่ต้องการชี้ให้ทุกคนที่กำลังใช้งานฟังก์ชั่นที่พวกเขาไม่จำเป็นต้องนับการประกาศและมีเพียงโค้ดข้างใน
Mathew Kirschbaum

8

Ruby, 44 ไบต์ (ฟังก์ชันของฟังก์ชัน: 37)

อาจมีศักยภาพที่จะตีกอล์ฟต่อไป

f=->n{n.to_s.chars.all?{|x|x>?0&&n%x.hex<1}}

fป้อนข้อมูลนำผ่านฟังก์ชั่น ตัวอย่างการใช้งาน:

f[128] # => true
f[12]  # => true
f[120] # => false
...

1
คุณสามารถเปลี่ยน.to_iไป.hexตั้งแต่ตัวเลขหลักเดียวจะเหมือนกันในฐาน 16 และสามารถเปลี่ยนไป==0 <1
ฮิสโทแกต

8

Python - 59 50 49 47 ไบต์

f=lambda n:all(c>'0'and 0==n%int(c)for c in`n`)

ฉันแน่ใจว่ามีวิธีที่เร็วกว่า ... โอ้ดี

แก้ไข - ขอบคุณ FryAmTheEggman สำหรับคำแนะนำการเล่นกอล์ฟ

แก้ไข 2 - FryAmTheEggman และอาจเขียนสิ่งนี้ในจุดนี้เช่นกัน

แก้ไข 3 - ยกมือถ้าคุณไม่รู้ว่า genexps เป็นอะไร ...แค่ฉัน?


โอ้ขอบคุณมาก! ฉันลืมทุกสิ่งเหล่านั้นไปเรื่อย ๆ (ฉันก็ไม่ได้ตระหนักว่าคุณสามารถทำได้น้อยกว่าตัวอักษรในแบบนั้น)
Kasran

f=lambda n:all([c>'0'and 0==n%int(c)for c in`n`])โอ้พลิกตรรกะยังดูเหมือนว่าจะร่นมันบิต: และไม่มีปัญหา :)
FryAmTheEggman

โอ้ฉันไม่ได้ตระหนักถึงแม้จะมีเป็นallวิธี
Kasran

จะ1>n%int(c)ทำงานอย่างไร
Sp3000

3
ทำไมต้องเป็นรายการความเข้าใจ? ใช้ genexp: all(c>'0'and 0==n%int(c)for c in`n`)ทำสิ่งเดียวกันโดยมี 2 ตัวอักษรน้อยลงและประหยัดการจัดสรรรายการ
Bakuriu

8

Pyth 11

!f%Q|vT.3`Q

นี่เป็นการรวมคำตอบของ@ isaacgและ@ xnor input % (eval(current_digit) or .3)มันกรองเอาตัวเลขจากการป้อนข้อมูลโดยการตรวจสอบค่าของ จากนั้นจะตรวจสอบว่าสตริงผลลัพธ์ว่างเปล่าหรือไม่

มาในรูปแบบที่มีความยาวเท่ากัน:

!f%Q|T.3jQT
!f|!T%QTjQT

ลองออนไลน์


5

Bash + coreutils 44 ไบต์

นิยามฟังก์ชั่นเต็มรูปแบบคือ:

f()((`tr 0-9 \10<<<$1``sed "s/./||$1%&/g"<<<$1`))

ฉันไม่แน่ใจว่าจะให้คะแนนสิ่งนี้ได้อย่างไรเพราะโดยปกติแล้วฟังก์ชั่นของเชลล์ใช้ชุดเดียว{}หรือ()เพื่อบรรจุส่วนของฟังก์ชั่น ฉันพบที่นี่ฉันยังสามารถใช้ double (())เพื่อบรรจุส่วนของฟังก์ชั่นซึ่งทำให้เกิดการขยายเลขคณิตซึ่งเป็นสิ่งที่ฉันต้องการที่นี่ ดังนั้นสำหรับตอนนี้ฉันนับเพียงหนึ่งคู่ของวงเล็บเหล่านั้น - การอภิปรายเพิ่มเติมเกี่ยวกับเรื่องนี้ยินดีต้อนรับ

เอาท์พุท:

$ for i in 128 12 120 122 13 32 22 42 212 213 162 204; do f $i; printf "%d " $?; done
1 1 0 1 0 0 1 0 1 0 1 0 $
$

เอ่อ - มันไม่ชัดเจนสำหรับฉันว่า 1s และ 0s เป็นที่ยอมรับหรือถ้าฉันต้องพิมพ์true/ false?
Digital Trauma

4

J - 14 ตัวอักษร

=:ร่างกายจะเป็นส่วนของฟังก์ชั่นหลัง ถ้าเราต้องการที่จะลดการนับจำนวนตัวอักษรสำหรับฟังก์ชั่นทั้งที่ 15 */@(0=,.&.":|])ถ่าน

f=:0*/@:=,.&.":|]

,.&.":เป็นวิธีที่สั้นที่สุดใน J เพื่อขยายจำนวนให้เป็นรายการของเลขทศนิยม: แปลงเป็นสตริง, แยกตัวเลขและแปลงตัวเลขแต่ละหลักกลับเป็นตัวเลข ,.&.":|]ใช้หมายเลขอินพุต ( ]) โมดูโล ( |) ตัวเลขเหล่านั้น 0*/@:=ผลตอบแทนจริงถ้าผลลัพธ์ทั้งหมดเป็น 0 มิฉะนั้นจะเป็นเท็จ

   f 162
1
   f every 204 212 213
0 1 0

3

Java - 121 102 97 79 78 ไบต์

ฉันเพิ่งรู้ว่าสิ่งนี้จะได้รับการอุดตันในภายหลัง โอ้ดี

boolean b(int a){int m=10,j,t=1;for(;m<a*10;m*=10){j=10*(a%m)/m;if(j==0||a%j>0)t=0;}return t>0;}

ฉันจะกลับมา.


1
ตอนนี้คุณสามารถตั้งชื่อฟังก์ชั่นของคุณได้ตามที่คุณต้องการ ฉันเปลี่ยนกฎเพื่อให้คุณนับการคำนวณภายในฟังก์ชั่นจริงเท่านั้น แต่ฟังก์ชั่นจะต้องกลับมาเป็นบูลีน นั่นคือปัจจุบันที่ 86 อักขระ
Mathew Kirschbaum

3

Haskell - 100 54 38

f x=all(\y->y>'0'&&x`mod`read[y]<1)$show x

ยังคงเรียนรู้คำวิจารณ์ชื่นชม


ฉันมีความคิดเห็นที่นี่ แต่ฉันลบมันโดยไม่ตั้งใจ ... อย่างไรก็ตามคำแนะนำบางอย่าง: 1) วางlengths พวกเขาไม่จำเป็น 2) แทนที่tด้วยคำจำกัดความ 3) elem y sไม่จำเป็น 4) /='0'สามารถย้ายไปที่ตัวกรองด้านซ้ายelem y sได้ 5) ในกรณี/='0'นี้เทียบเท่า>'0'เพราะทุกตัวอักษรเป็นตัวเลข 6) ใส่modbackticks ดังนั้นมันจะกลายเป็นมัด 7) ใส่ทุกอย่างไว้ในบรรทัดเดียว
Zgarb

1 และ 3 มาจากเมื่อฉันพยายามทำมันในวิธีที่แตกต่างและกู้รหัส ขอบคุณสำหรับเคล็ดลับ
globby

1
ข้อเสนอแนะของฉัน: แทนการใช้ที่คุณควรใช้s==filter(...)s all(...)sตอนนี้เพราะจะปรากฏขึ้นครั้งเดียวในการแสดงออกของคุณสามารถแทนที่ด้วยนั้นความหมายและการลดลงs whereอีกทั้ง==0คุณสามารถใช้<1แทน
ภูมิใจ haskeller

การปรับปรุงที่ดีเยี่ยมจากเวอร์ชั่นแรก!
ภูมิใจ haskeller

ฉันคิดว่าคุณยังคงสูญเสียหนึ่งไบต์ถ้าคุณแทนที่โดยall(\y->...)$show x and[...|y<-show x]
Zgarb

2

CJam, 15 ไบต์

{_Abf{_g{%}*}:|!}

นี่คือบล็อกสิ่งที่ใกล้เคียงที่สุดกับฟังก์ชันใน CJam ฉันนับร่างกายเท่านั้น (นั่นคือการละทิ้งวงเล็บปีกกา) คุณสามารถใช้มันได้ดังต่อไปนี้:

128{_Abf{_g{%}*}:|!}~

หรือถ้าคุณต้องการทดสอบชุดของอินพุตคุณสามารถทำได้

[128 12 120 122 13 32 22 42 212 213 162 204]{{_Abf{_g{%}*}:|!}~}%

บล็อกใบ0(เท็จ) หรือ1(จริง) บนสแต็กเพื่อระบุผลลัพธ์ (CJam ไม่มีประเภทบูลีน)

ทดสอบที่นี่

คำอธิบาย:

_               "Duplicate input.";
 Ab             "Get base-10 digits.";
   f{      }    "This maps the block onto the list of digits, supplying the input each time.";
     _g         "Duplicate digit, get signum S (0 or 1).";
       { }*     "Repeat this block S times.";
        %       "Take input modulo digit.";
                "This leaves an array of zeroes for divisible digits, non-zeroes
                 for non-divisible digits, and non-zero junk for zeroes.";
            :|  "Fold OR onto this list. One could also sum the list with :+";
              ! "Logical NOT. Turns 0 into 1, and non-zero values into 0.";

ทางเลือก 15 ไบต์เช่นกัน

{:XAb{X\_X)?%},!}

คำอธิบาย

:X              "Store input in X.";
  Ab            "Get base-10 digits.";
    {       },  "Filter this list by the result of the block.";
     X\         "Push another copy of X, swap with digit.";
       _        "Duplicate digit.";
        X)      "Push X+1.";
          ?     "Select digit itself or X+1, depending on whether digit is 0 or not.";
           %    "Take modulo. X%(X+1) will always be nonzero for positive integers.";
              ! "Logical NOT. Turns an empty list into 1 and a non-empty list into 0.";

2

CJam, 15 ไบต์

{_Abf{_{%}1?}1b!}

{}เป็นสิ่งที่ใกล้เคียงที่สุดกับฟังก์ชั่นใน CJam ฉันแค่นับเนื้อหาของฟังก์ชั่น

ใช้มันแบบนี้:

128{_Abf{_{%}1?}1b!}~

ที่จะได้รับอย่างใดอย่างหนึ่ง1(ถ้าจำนวนหารได้) หรือ0(ถ้าตัวเลขไม่หารด้วยตัวเลข)

ลองออนไลน์ได้ที่นี่

คำอธิบาย

_Ab                "Copy the number and split it to its digits";
   f{      }       "For each digit, run this code block on the number";
     _{%}1?        "If the digit is 0, put 1, otherwise perform number modulus digit";
            1b     "We now have an array of modulus corresponding to each digit. Sum it up";
              !    "Negate the sum. If all digits were divisible, sum of modules will be"
                   "0, thus answer should be 1 and vice versa";

ฉันอาจจะพลาดอะไรบางอย่าง แต่หลังจากอ่าน CJam อย่างรวดเร็วแล้วบางสิ่งดูเหมือนจะไม่สมเหตุสมผล: จะAbแยกตัวเลขได้อย่างไร ดูเหมือนว่าเพิ่งแปลงเป็นฐาน 10 นอกจากนี้% จะทราบได้อย่างไรว่าจะปรับเปลี่ยนตามจำนวนและไม่ใช่แค่ตัวเลขถัดไปเนื่องจากดูเหมือนว่าตัวเลขถัดไปจะเป็นถัดไปในสแต็ก
Mathew Kirschbaum

ตอบคำถามของคุณทั้งหมดจะยุ่งยาก มันจะง่ายมากที่จะเรียนรู้โดยการวาง ed ตามตัวละครแต่ละตัวในรหัส ลองใช้งาน128{ed_edAedbedf{ed_ed{ed%ed}1ed?ed}ed1edbed!ed}~
เครื่องมือเพิ่มประสิทธิภาพ

1
คำตอบสำหรับคำถามเฉพาะ: การทำฐาน 10 ให้อาร์เรย์ของตัวเลขฐานที่แปลง 10 ซึ่งเป็นตัวเลขหลักในกรณีนี้ %ใช้ตัวเลขสองตัวสุดท้าย (ในกรณีนี้) และคำนวณ mod ตัวเลขสองตัวสุดท้ายที่นี่เป็นจำนวนจริงและตัวเลข (เสมอ)
เครื่องมือเพิ่มประสิทธิภาพ

โอเคขอบคุณสำหรับคำแนะนำ!
Mathew Kirschbaum

2

C89, 43 ไบต์

unsigned char d(int n, int c) {
        int a=n%10;return!n||a&&!(c%a)&&d(n/10,c);
}

C89 ไม่มีประเภทบูลีน หวังว่าจะได้ผล ฉันยังใช้พารามิเตอร์ตัวที่สองเพื่อส่งสำเนาของหมายเลขดั้งเดิมผ่านสแต็ก แต่คำจำกัดความสามารถเป็นอะไรก็ได้ เพื่อให้ได้ผลลัพธ์ที่ถูกต้องคุณเพียงแค่เรียกใช้ฟังก์ชันที่มีค่าเดียวกันสำหรับพารามิเตอร์ทั้งสอง ( d(128, 128))

แก้ไข:ใช้การแก้ไขที่แนะนำโดยผู้ใช้ที่ไม่ระบุชื่อ


ลองดูที่codegolf.stackexchange.com/review/suggested-edits/17160มีคนให้คำแนะนำเกี่ยวกับการเล่นกอล์ฟให้กับคุณ
Justin

เฉพาะกับกฎ หนึ่งพารามิเตอร์
edc65

ใช่โพสต์นี้จริง ๆ แล้วทำไมฉันถึงตัดสินใจที่จะทำตามกฎเพราะมันดูเหมือนไม่ถูกต้องที่ผู้ใช้ควรทำซ้ำแทนโปรแกรม
Mathew Kirschbaum

ฉันเดาว่าฉันจะต้องเพิ่มฟังก์ชั่น wrapper การประกาศฟังก์ชั่นนั้นเพิ่มลงในการนับไบต์หรือไม่?
MarcDefiant

2

C11 - 44 ไบต์ในเนื้อหาของฟังก์ชัน

รุ่น C อื่นไม่ใช่แบบเรียกซ้ำและไม่มีข้อยกเว้นจุดทศนิยม

bool digit_multiple(int i)
{
    for(int n=i;i%10&&n%(i%10)<1;i/=10);return!i;
}

สิ่งนี้จะทำงานใน C ++, Java และภาษา C-like อื่น ๆ ส่วนใหญ่

แก้ไขเพื่อรวมการปรับปรุงความคิดเห็นของพรีโม่


1
เวอร์ชันที่คอมไพล์ใน Java (1.7.0_45-b18): int n=i;for(;i%10>0&&n%(i%10)<1;i/=10);return i<1;หนึ่งไบต์สั้นกว่าโค้ดของ OP
โม่

2

Julia 32 25 23

ปรับปรุงโดยใช้ตัวเลข

แก้ไขปัญหาด้วยจำนวนลบ

selfDivides(x)=sum(x%digits(x).^1.)==0

วิธีเก่า ๆ

ตัวเลขทั้งหมดหารด้วยจำนวนผลรวมของเศษเหลือทั้งหมดคือ 0 เช่นเดียวกับตัวเลขอื่น ๆ มีปัญหากับจำนวนลบ

selfDivides(x)=sum(x.%(Float64["$x"...]-48))==0

เอาท์พุต

[selfDivides(x) for x in [128,12,120,122,13,32,22,42,212,213,162,204]]
12-element Array{Any,1}:
  true
  true
 false
  true
 false
 false
  true
 false
  true
 false
  true
 false

วิธีการที่ปรับปรุงแล้วยังรองรับ BigInt

selfDivides(BigInt(11111111111111111111111111111111111111112))
true

อย่างไรก็ตาม

selfDivides(BigInt(11111111111111111111111111111111111111113))
false

เพราะ

BigInt(11111111111111111111111111111111111111113) %3
1

2

C / C ++, 58 ไบต์ (44 ในร่างกาย)

เรียกใช้พฤติกรรมที่ไม่ได้กำหนด (ดูความคิดเห็น)

int d(int i){int j=i;while(i&&!(j%(i%10)))i/=10;return!i;}

trueและfalse เป็น 1 และ 0 แต่boolอย่าลังเลที่จะเพิ่มอักขระหนึ่งตัวในลายเซ็นเพื่อส่งคืน

และเพื่อความสนุกสนานเวอร์ชันเรียกซ้ำที่มีขนาดเล็กลงหากคุณอนุญาตให้โทรจากแบบฟอร์ม r(128,128)

แก้ไข : กฎไม่อนุญาตในขณะนี้:

C / C ++, 53 ไบต์ (33 ในร่างกาย)

int r(int i,int j){return!i||!(j%(i%10))&&r(i/10,j);}


2
# 1 ตายด้วยข้อยกเว้นจุดลอยตัวสำหรับตัวเลขที่มี 0 เพราะ j% (i% 10) จะผิดกฎหมายสำหรับ i% 10 = 0
SBI

จุดลอยยกเว้น? แปลก. มันทำงานได้อย่างสมบูรณ์ในคอมไพเลอร์ของฉัน แต่คุณพูดถูกมันเป็นพฤติกรรมที่ไม่ได้กำหนด ไม่แน่ใจว่าท่าทาง PCG ทั่วไปของ UB ที่ขึ้นกับคอมไพเลอร์คืออะไร
etheranger

"UB ที่ขึ้นอยู่กับผู้รวบรวม" คืออะไร? ไม่ว่าจะเป็น UB หรือไม่ใช่ (และหารด้วยศูนย์หรือค่อนข้างโมดูโลศูนย์เป็น UB จริง ๆ ) ไม่ควรอนุญาตให้ใช้ UB เพราะแท้จริงแล้วอาจมีอะไรเกิดขึ้น เราอาจสมมติว่าโปรแกรมของคุณจะทำงานบนเครื่องที่จะระเบิดและฆ่าทุกคนที่อยู่รอบ ๆ มันเมื่อมีการหารด้วยศูนย์เกิดขึ้น ตอนนี้ฉันแน่ใจว่าคุณต้องการให้พวกเราทุกคนมีชีวิตอยู่ ... C มีแนวคิดเกี่ยวกับพฤติกรรมที่กำหนดโดยการนำไปใช้ แต่การหารด้วยศูนย์จะไม่ตกอยู่ภายใต้สิ่งนั้น
Jeroen Mostert

2
@etheranger: การหารด้วย 0 เรียกว่าข้อยกเว้นจุดลอยตัวด้วยเหตุผลทางประวัติศาสตร์: stackoverflow.com/questions/16928942/ …
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

2
@JeroenMostert: ฉันจะพูดมากกว่า 90% ของคำตอบทั้งหมดในเว็บไซต์นี้เรียก UB ตราบใดที่จะทำงานร่วมกับบางคอมไพเลอร์ในบางเครื่องคำตอบที่ถูกต้องคือการพิจารณา
Dennis

2

R: 72 67 65

ฟังก์ชั่น

f<-function(a)!(anyNA(a%%(d=as.double(strsplit(paste0(a),"")[[1]])))|sum(a%%d))

ขอบคุณ @AlexA และ @plannapus สำหรับการประหยัด

ทดสอบการทำงาน

i=c(128,12,120,122,13,32,22,42,212,213,162,204)
for(a in i){print(f(a))}
[1] TRUE
[1] TRUE
[1] FALSE
[1] TRUE
[1] FALSE
[1] FALSE
[1] TRUE
[1] FALSE
[1] TRUE
[1] FALSE
[1] TRUE
[1] FALSE

ฉันนับ 70 ไบต์ในร่างกายการทำงานของคุณในขณะนี้ไม่ได้ 72. แต่คุณจะได้รับมันลงไป 67 d=as.double(strsplit(toString(a),"")[[1]]);!(anyNA(a%%d)|sum(a%%d))ใช้ :)
อเล็กซ์ A.

@AlexA ขอบคุณ หนึ่งในความพยายามครั้งแรกของฉันด้วย wih R. จะกลับมาอีกแน่นอน :)
MickyT

@MickyT paste(a)แทนที่จะtoString(a)ให้ผลลัพธ์เดียวกัน
plannapus

@plannapus ขอบคุณเคล็ดลับเล็ก ๆ น้อย ๆ เรียบร้อย ต้องจำไว้ว่า
MickyT

1

GNU Awk: 53 ตัวอักษร

ส่วนที่นับ:

for(;++i<=split($1,a,//);)r=r||!a[i]||v%a[i];return!r

ฟังก์ชั่นทั้งหมด:

function self_divisible(v, i, r)
{
    for (; ++i <= split($1, a, //); )
        r = r || ! a[i] || v % a[i]

    return ! r
}

เนื่องจาก Awk ไม่มีค่าบูลีนให้ส่งคืน 1 tor true และ 0 เป็นเท็จ


1

JavaScript (ES6) 30

ฟังก์ชั่นด้วยพารามิเตอร์ตัวเลขหนึ่งตัว การใช้% และการลบไม่จำเป็นต้องใช้ตัวพิมพ์พิเศษ '0' เนื่องจาก 0% 0 คือ NaN ใน JavaScript

แก้ไข DocMax 1 char ขอบคุณ

F=n=>[for(d of t=n+'')t-=n%d]&&t==n 

เพียงเพื่อความสนุกใช้กฎที่ไม่ถูกต้องเกี่ยวกับการไม่นับลายเซ็นฟังก์ชัน 4

Check=(n,t=n+'',q=[for(d of t)n-=t%d])=>t==n

ทดสอบในคอนโซล FireFox / FireBug

console.log([128, 12, 120, 122, 13, 32, 22, 42, 212, 213, 162, 204]
.map(x=>+x + ' -> ' + F(x)).join('\n'))

เอาท์พุต

128 -> true
12 -> true
120 -> false
122 -> true
13 -> false
32 -> false
22 -> true
42 -> false
212 -> true
213 -> false
162 -> true
204 -> false

ฉันจะบอกว่าไม่ให้ใส่สตริง
Mathew Kirschbaum

1
คอนโซล Firefox มีความสุขกับการแทนที่of(t=n+'')ด้วยเพียงแค่of t=n+''การบันทึก 1
DocMax

1

PHP: 85 ไบต์ (64 ไบต์บนตัวเครื่อง)

เพื่อให้ฟังก์ชั่นนี้ใช้งานได้เพียงแค่ส่งสตริงหรือตัวเลข

0 จะส่งคืนเท็จอย่างถูกต้อง

รหัส:

function f($n,$i=0){for($n.='';$n[$i]&&$t=!($n%$n[$i++]););return$t&&$i==strlen($n);}

กรุณาอย่าตั้งค่าพารามิเตอร์ที่ 2!

Javascript: 76 ไบต์ (61 ไบต์บนตัวเครื่อง)

นี่คือการเขียนซ้ำของฟังก์ชั่นก่อนหน้า

ไม่ค่อยมีการเปลี่ยนแปลงระหว่างทั้งสองเวอร์ชัน

นี่คือรหัส:

function f(n){for(i=0,n+='';n[i]/1&&(t=!(n%n[i++])););return t&&i==n.length}

Polyglot: Javascript + PHP 187 217 ไบต์ (76 84 ไบต์โดยไม่ต้องสำเร็จรูป):

ทำไมฉันทำมันได้?

เพราะเหตุผลและอาจเป็นเพราะฉันทำได้!

เพียงแค่ละเว้นข้อผิดพลาดใน PHP: มันทำงานได้!
ไม่ต้องการอีกต่อไปสิ่งนี้ได้รับการแก้ไขโดยการลบ 3 ไบต์

นี่คือผลงานชิ้นเอก:

if('\0'=="\0"){function strlen($s){return $s['length'];}}
function toString(){return'';}
function f($n){for($i=0,$n=$n.toString();$n[$i]/1&&($t=!($n%$n[$i++])););return $t&&$i==strlen($n);}

คุณสามารถเรียกใช้รหัสนี้ได้ทั้งบนคอนโซลและล่าม PHP!


เวอร์ชั่นเก่า:

if('\0'=="\0"){function strlen($s){return $s['length'];}}
function s($s){return('\0'=="\0")?$s+'':str_replace('','',$s);}
function f($n,$i){for($i=0,$n=s($n);$n[$i]/1&&($t=!($n%$n[$i++])););return $t&&$i==strlen($n);}

"และผ่านในพารามิเตอร์ตัวเลขเดียวเท่านั้น" หากไม่มีสิ่งนี้คุณสามารถประเมิน ($ x) และส่งรหัสทั้งหมดใน $ x
abc667

@ abc667 ขออภัย แต่ฉันไม่เข้าใจ
Ismael Miguel

1

คู่, 33 (39 รวมถึงการตั้งค่าฟังก์ชั่น)

การใช้การแปลงตัวเลขเป็นเมทริกซ์:

f=@(a)sum(mod(a./(num2str(a)-48),1))==0

หารตัวเลขตามจำนวนเมทริกซ์ X โดยที่ X ทำโดยแปลงตัวเลขเป็นสตริงและลบ 48 เพื่อเปลี่ยนจากค่า ASCII เป็นตัวเลขอีกครั้ง รับ modulo 1 เพื่อรับส่วนทศนิยมของแต่ละส่วนยืนยันว่าสิ่งเหล่านี้ทั้งหมดเป็นศูนย์ (ถ้ามี NaN เนื่องจากเป็น / 0 ผลรวมจะเป็น NaN และไม่ใช่ศูนย์)

ตัวอย่างอินพุตโดยใช้ www.octave-online.net:

f=@(a)sum(mod(a./(num2str(a)-48),1))==0
for j=[128,12,120,122,13,32,22,42,212,213,162,204]
f(j)
end

เอาท์พุท:

ans =  1
ans =  1
ans = 0
ans =  1
ans = 0
ans = 0
ans =  1
ans = 0
ans =  1
ans = 0
ans =  1
ans = 0

เราจะทดสอบสิ่งนี้ได้อย่างไร
Ismael Miguel

octave-online.net - ป้อนคำนิยามรหัสจากด้านบนแล้ว (ตัวอย่าง) f (128) จะเพิ่มผลลัพธ์
Jørgen

ฉันพบคอมไพเลอร์และลองก่อนถาม แต่ดูเหมือนว่าจะทำงานได้ดี (ยกเว้นf(123)ซึ่งหารด้วย 1, 2 และ 3) แต่ใช้งานได้กับกรณีทดสอบที่ให้ไว้
Ismael Miguel


1

BASH - 117 ตัวอักษร

f(){ [[ $1 =~ 0 ]]&& return 0 || r=;n=$1;for((i=0;i<${#n};i++));do r=$(($r+${n}%${n:$i:1}));done;return $(($r==0));}

การทดสอบ

for N in 128 12 120 122 13 32 22 42 212 213 162 204; do
  f $N
  echo "${N} ->  $?"
done

128 ->  1
12 ->  1
120 ->  0
122 ->  1
13 ->  0
32 ->  0
22 ->  1
42 ->  0
212 ->  1
213 ->  0
162 ->  1
204 ->  0

1

PHP - 74 71 64 ตัวละคร

แข็งแรงเล่นกอล์ฟ:

function t($n){while($n>1){if(!($b=$n%10)||($n%$b)){return 0;}$n/=10;}return 1;}

หัก Golfed:

function t($n){
    while($n>1){
        if( !($b=$n%10) || ($n%$b) )
            { return 0; }
        $n/=10;
    }
    return 1;
}

ผลการทดสอบ:

(รหัส)

$ans = array(128,12,120,122,13,32,22,42,212,213,162,204);
foreach($ans as $a)
{ echo "$a -> ".(t($a)?"True":"False").PHP_EOL; }

(ขาออก)

128 -> True
12 -> True
120 -> False
122 -> True
13 -> False
32 -> True
22 -> True
42 -> True
212 -> True
213 -> True
162 -> False
204 -> False
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.