พับจำนวนเต็มเพื่อประหยัดพื้นที่!


20

นักคณิตศาสตร์บ้าเป็นเจ้าของตัวเลขจำนวนมากและพื้นที่ที่เขาทิ้งมี จำกัด เพื่อช่วยให้บางเขาต้องพับจำนวนเต็ม แต่น่าเสียดายที่เขาขี้เกียจจริงๆ งานของคุณหากคุณต้องการช่วยเขาคือการสร้างฟังก์ชั่น / โปรแกรมที่พับจำนวนเต็มบวกที่กำหนดสำหรับความบ้าคลั่งจำนวนของเรา

วิธีการพับจำนวนเต็ม?

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

  1. 1 + 7 + 8 + 2 = 18ได้รับผลรวมของตัวเลขของ: 1782หารเท่า ๆ กันโดยดังนั้นจำนวนต่อไปคือ181782 / 18 = 99

  2. 99ไม่หารเท่า ๆ กันโดยเหตุนี้เราใช้เวลาที่เหลือ:9 + 9 = 1899 % 18 = 9

  3. 9หารอย่างเห็นได้ชัดโดยเราจึงแบ่งมันและได้รับ91

ผลลัพธ์คือ3เนื่องจากต้องการการดำเนินการ 3 ครั้งเพื่อให้สามารถเข้าถึง1ได้

กฎและข้อกำหนด

  • จำนวนเต็มบางคนอาจจะมีผลรวมของตัวเลขเท่ากับ1เช่นหรือ10 100โปรแกรมของคุณไม่จำเป็นต้องจัดการกับกรณีดังกล่าว ซึ่งหมายความว่าคุณจะรับประกันได้ว่าจำนวนเต็มที่ได้รับเป็นอินพุตไม่มีผลรวมของตัวเลขเท่ากับ1และไม่มีการดำเนินการกับจำนวนเต็มที่กำหนดจะส่งผลให้ตัวเลขที่มีผลรวมของตัวเลข1(ยกเว้น1ตัวมันเองซึ่งก็คือ " เป้าหมาย ") ตัวอย่างเช่นคุณจะไม่ได้รับ10หรือ20เป็นอินพุต

  • 1การป้อนข้อมูลจะเป็นจำนวนเต็มบวกที่สูงกว่า

  • มีการใช้ช่องโหว่เริ่มต้น

  • คุณสามารถใช้อินพุทและเอาท์พุทให้โดยใด ๆ ค่าเฉลี่ยมาตรฐาน


กรณีทดสอบ

อินพุต -> เอาท์พุท

2 -> 1
5 -> 1
9 -> 1
18 -> 2
72 -> 2
152790 -> 2
152 -> 3
666 -> 3
777 -> 3
2010 -> 3
898786854 -> 4

นี่คือโปรแกรมที่ช่วยให้คุณเห็นภาพกระบวนการและลองกรณีทดสอบเพิ่มเติม


นี่คือดังนั้นรหัสที่สั้นที่สุดในแต่ละภาษา (คะแนนเป็นไบต์) ชนะ!


แรงบันดาลใจจากความท้าทายนี้แม้ว่ามันอาจจะดูไม่เกี่ยวข้องในตอนแรก
Mr. Xcoder

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

ในขณะที่8987868546เป็นการป้อนข้อมูลที่ถูกต้องมันจะทำลายเครื่องมือทดสอบของคุณและยังหลาย ๆ (ถ้าไม่ทั้งหมด) ของคำตอบ ...
มิสชา

@MischaBehrend ตัวอย่างของคุณไม่ใช่อินพุตที่ถูกต้อง ฉันคิดว่าคุณละเมิดกรณีทดสอบครั้งสุดท้ายของฉัน อินพุตที่ถูกต้องคือ898786854ไม่ใช่8987868546(คุณได้เพิ่ม6ในตอนท้าย)
Mr. Xcoder

nvm ... ควรอ่านกฎข้อแรกทั้งหมด ... ออกจากที่นี่เพื่อให้คุณรู้ว่าทำไมฉันคิดว่ามันถูกต้อง:มันไม่ใช่ความผิดพลาด ... ฉันเปลี่ยนมันโดยเจตนาที่จะทดสอบสคริปต์เหล่านี้ ... และอ่านกฎมันเป็นอินพุตที่ถูกต้อง ผลรวมของตัวเลขทั้งหมดใน8987868546 ไม่เท่ากับ 1 (ตรงตามกฎ 1 ) และ8987868546เป็นจำนวนเต็มบวกสูงกว่า 1 (ตรงตามกฎ 2 )
Mischa

คำตอบ:


6

05AB1E , 13 12 ไบต์

[¼DSO‰0Kθ©#®

ลองออนไลน์!

คำอธิบาย

[               # start loop
 ¼              # increment counter
  D             # duplicate current value
   SO           # sum the digits in the copy
     ‰          # divmod the current value by its digit-sum
      0K        # remove 0 from the resulting list
        θ       # pop the last element
         ©      # store a copy in register
          #     # if the current value is 1, break
           ®    # push the copy from register
                # implicitly output counter

6

Python 2 , 63 57 ไบต์

-1 ต้องขอบคุณมนุษย์โดยสิ้นเชิง
-1 ขอบคุณ Mr. Xcoder
-4 ขอบคุณ reffu

def f(n):a=sum(map(int,`n`));return n>1and-~f(n%a or n/a)

ลองออนไลน์!




1
57 bytesขอโทษด้วยที่ทำให้คำตอบนี้เป็นของตัวเองในตอนแรก มันสมเหตุสมผลมากขึ้นในการแสดงความคิดเห็น
reffu

5

Haskell, 85 78 ไบต์

f 1=0
f n|r<1=1+f(n`div`s)|1<2=1+f r where s=sum(read.pure<$>show n);r=n`rem`s

บันทึกแล้ว 7 ไบต์ขอบคุณ Bruce Forte

ลองออนไลน์


บันทึกไบต์เพิ่มเติมโดยใช้divModและวางwhere: ลองออนไลน์!
Laikoni

@Laikoni ว้าวมันค่อนข้างจะปรับปรุง! โปรดโพสต์เป็นคำตอบอื่น มันแตกต่างจากของฉันมากพอ BTW: whereผมกำลังมองหาเคล็ดลับในการกำจัดของ ฉันจะใช้สิ่งนี้ในอนาคต :)
Cristian Lupascu

sum[read[d]|d<-show n]บันทึก byte
nimi

5

JavaScript (ES6), 66 58 51 49 ไบต์

รับอินพุตเป็นจำนวนเต็ม ผลตอบแทนfalseสำหรับ0หรือ1และพ่นข้อผิดพลาดล้นเมื่อมันพบหมายเลขใด ๆ 1ที่มีตัวเลขเพิ่มขึ้นถึง

f=n=>n>1&&f(n%(x=eval([...""+n].join`+`))||n/x)+1
  • 8 ไบต์บันทึกไว้ด้วยความช่วยเหลือจากจัสติน

ทดสอบมัน

o.innerText=(

f=n=>n>1&&f(n%(x=eval([...""+n].join`+`))||n/x)+1

)(i.value=898786854);oninput=_=>o.innerText=f(+i.value)
<input id=i type=number><pre id=o>


1
คุณสามารถบันทึกไบต์จำนวนหนึ่งด้วยการรวมตัวเลขโดยใช้eval(array.join`+`)หรือไม่
Justin Mariner

ฉันทำได้แน่นอน @JustinMariner - คุณทำให้ฉันเป็นแบบนั้น! ขอบคุณ :)
Shaggy

4

Huskขนาด 12 ไบต์

←€1¡Ṡ§|÷%oΣd

ลองออนไลน์!

คำอธิบาย

←€1¡Ṡ§|÷%oΣd  Implicit input, e.g. n=1782
    Ṡ§|÷%oΣd  This part defines the transformation.
         oΣ   Sum of
           d  digits: s=18
    Ṡ   %     n mod s: 0
     §|       or (take this branch if last result was 0)
       ÷      n divided by s: 99
   ¡          Iterate the transformation: [1782,99,9,1,1,1,...
 €1           Index of 1 (1-based): 4
←             Decrement: 3
              Print implicitly.


3

Japtap , 22 19 17 ไบต์

-3 ไบต์ขอบคุณ @Shaggy
-2 ไบต์ขอบคุณ @ETHproductions


ìx
>1©1+ßU%VªU/V

ลองออนไลน์!



1
ที่จริงแล้วคุณสามารถเปลี่ยนs_¬เป็นìบันทึกอีกสองไบต์ :-)
ETHproductions

@ ETHproductions โอ้เยี่ยมจริงๆขอบคุณ!
Justin Mariner

2

เรติน่า 100 ไบต์

$
;
{`(.+);
$1$*1;$&
(?<=;.*)\d(?=.*;)
$*
.*;1;(.*)
$.1
r`(1)*(\3)*;(1+);
$#1;$#2;1
0;(.*);|;.*;
$1;

ลองออนไลน์! ลิงก์มีเฉพาะกรณีทดสอบขนาดเล็กเนื่องจากขนาดใหญ่ใช้เวลานานเกินไป


2

Mathematica, 73 ไบต์

(t=#;For[r=0,t>1,r++,If[(s=Mod[t,g=Tr@IntegerDigits@t])<1,t=t/g,t=s]];r)&

สามารถ==0ถูกแทนที่ด้วย<1?
Mr. Xcoder

@ Mr.Xcoder ใช่แน่นอน! ฉันทำรุ่นที่เรียงลำดับแล้ว ...
J42161217

2

PHP, 68 + 1 ไบต์

เอาท์พุท unary:

for($n=$argn;$n>1;$n=$n%($s=array_sum(str_split($n)))?:$n/$s)echo 1;

เอาต์พุตทศนิยม 73 + 1 ไบต์:

for($n=$argn;$n>1;$i++)$n=$n%($s=array_sum(str_split($n)))?:$n/$s;echo$i;

ทำงานเป็นท่อที่มี-nRหรือลองออนไลน์


ตัวดำเนินการ Elvis ต้องการ PHP 5.3 หรือใหม่กว่า สำหรับ PHP รุ่นเก่าให้แทนที่?:ด้วย?$n%$s:(+5 ไบต์)





1

เยลลี่ 12 ไบต์

dDS$Ṛȯ/µÐĿL’

ลองออนไลน์!


วิธีการที่น่าสนใจ! ตอนนี้เรากำลังรอโจนาธาน: P
Mr. Xcoder

@ Mr.Xcoder ฉันไม่คิดว่าดังนั้นเวลานี้ :)
เอริก Outgolfer

ฉันไม่ใช่หรือเป็นเรื่องตลก :)
นาย Xcoder


1

Perl, 71ไบต์, 64ไบต์, 63 ไบต์

-pl

$c=0;while($_>1){$s=0;$s+=$_ for/./g;$_=$_%$s?$_%$s:$_/$s;++$c};$_=$c

ลองออนไลน์

แก้ไข: บันทึกแล้ว 7 ไบต์ขอบคุณความคิดเห็นของ Xcali

-p

while($_>1){$s=0;$s+=$_ for/./g;$_=$_%$s?$_%$s:$_/$s;++$c}$_=$c

แก้ไข: ตั้งแต่ 5.14 การทดแทนที่ไม่ทำลาย s /// r

-pl

while($_>1){$s=eval s/\B/+/gr;$_=$_%$s?$_%$s:$_/$s;++$c}$_=$c

คือ-plด้านบนควรจะเป็นธงบรรทัดคำสั่งแทน?
Erik the Outgolfer

ใช่พวกเขาเป็นตัวเลือก Perl
Nahuel Fouilleul

คุณควรนับ-plธงตามโพสต์นี้
Erik the Outgolfer

ฉันนับ 69 ไบต์ +2 สำหรับตัวเลือก pl ถูกต้องหรือไม่
Nahuel Fouilleul

คุณสามารถตีกอล์ฟลงได้เล็กน้อย $cไม่จำเป็นต้องเริ่มต้นใหม่ มันจะเริ่มต้นที่undef0 เครื่องหมายอัฒภาคหลังจากการปิดสามารถไป -lนอกจากนี้คุณไม่จำเป็นต้อง ไม่จำเป็นต้องใช้อินพุตหลายค่าในการรันครั้งเดียว
Xcali


1

Gaiaขนาด 13 ไบต์

-@{:ΣZ¤∨)‡}°\

ลองออนไลน์!

คำอธิบาย

-              Push -1 (this will be the counter)
 @             Push input (the starting number)
  {:ΣZ¤∨)‡}°   Repeat this block until the results of 2 consecutive runs are the same:
   :            Copy the number
    Σ           Digital sum
     Z          Divmod number by digital sum
      ¤         Swap
       ∨        Logical or: left-most non-zero out of (number mod sum, number div sum)
        )‡      Increment the counter
            \  Delete the final 1, implicitly print the counter

1

Matlab, 150 ไบต์

function[d]=X(x) 
d=0;while ~strcmp(x,'1')z='sum(str2num(x(:)))';a=eval(['rem(',x,',',z,')']);y=num2str(a*(a>0)+eval([x,'/',z])*(a==0));x=y;d=d+1;end

อินพุตควรถูกกำหนดให้กับฟังก์ชันเป็นสตริงเช่น X ('152')

ฟังก์ชั่นทำงานโดยในขณะที่วนลูปและเพิ่มค่า d x=y;สายเป็นสิ่งจำเป็นเพื่อหลีกเลี่ยงข้อผิดพลาดของ Matlab พยายามที่จะอ่านและเขียนทับค่าตัวแปรในเวลาเดียวกันเห็นได้ชัดซึ่งเป็นหนึ่งใหม่กับฉัน

Ungolfed:

function[d]=X(x) 
d=0;
while ~strcmp(x,'1')
    z='sum(str2num(x(:)))';
    a=eval(['rem(',x,',',z,')']);
    y=num2str(a*(a>0)+eval([x,'/',z])*(a==0));
    x=y;
    d=d+1;
end


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