Gấp số nguyên để tiết kiệm không gian!


20

Nhà toán học điên này sở hữu một bộ sưu tập lớn các con số, và do đó, không gian mà anh ta để lại khá hạn chế. Để cứu một số người, anh ta phải gấp số nguyên của mình, nhưng tiếc là anh ta thực sự lười biếng. Nhiệm vụ của bạn, nếu bạn muốn giúp anh ta, là tạo ra một hàm / chương trình có thể gấp một số nguyên dương cho trước cho số người điên của chúng tôi.

Làm thế nào để gấp một số nguyên?

Nếu nó chia đều cho tổng các chữ số của nó, chia nó cho tổng các chữ số của nó. Nếu nó không đáp ứng yêu cầu đó, hãy lấy phần còn lại của nó khi chia cho tổng các chữ số của nó. Lặp lại quá trình cho đến khi kết quả đạt được 1. Số nguyên gấp là số lượng thao tác bạn phải thực hiện. Hãy lấy một ví dụ (giả sử 1782):

  1. Lấy tổng các chữ số của nó : 1 + 7 + 8 + 2 = 18. 1782là số chia hết cho 18, nên số tiếp theo là 1782 / 18 = 99.

  2. 99không chia hết cho 9 + 9 = 18, do đó chúng ta lấy phần còn lại : 99 % 18 = 9.

  3. 9rõ ràng là chia hết cho 9, vì vậy chúng tôi chia nó và thu được 1.

Kết quả là 3, bởi vì 3 thao tác được yêu cầu để đạt được 1.

Quy tắc và thông số kỹ thuật

  • Một số số nguyên có thể có tổng các chữ số bằng 1, chẳng hạn như 10hoặc 100. Chương trình của bạn không cần xử lý những trường hợp như vậy. Điều đó có nghĩa là, bạn sẽ được đảm bảo rằng số nguyên được cung cấp làm đầu vào không có tổng các chữ số bằng 1và không có thao tác nào với số nguyên đã cho sẽ dẫn đến một số có tổng các chữ số 1(ngoại trừ 1chính nó là " Mục tiêu"). Ví dụ, bạn sẽ không bao giờ nhận được 10hoặc 20làm đầu vào.

  • Đầu vào sẽ là một số nguyên dương cao hơn 1.

  • Lỗ hổng mặc định áp dụng.

  • Bạn có thể lấy đầu vào và cung cấp đầu ra theo bất kỳ giá trị trung bình tiêu chuẩn nào .


Các trường hợp thử nghiệm

Đầu vào -> Đầu ra

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

Đây là một chương trình cho phép bạn hình dung quá trình và thử nhiều trường hợp thử nghiệm hơn.


Đây là , vì vậy mã ngắn nhất trong mỗi ngôn ngữ (tính bằng byte) sẽ thắng!


Lấy cảm hứng từ thử thách này , mặc dù lúc đầu nó có vẻ không liên quan.
Ông Xcoder

3
Điều này sẽ hoạt động như một giải pháp ngăn chặn, nhưng về lâu dài, nhà toán học nên thực sự xem xét việc mua một trong những Khách sạn của Hilbert . Bạn luôn có thể tìm thấy một số phòng không sử dụng ở một trong số đó.
Ray

trong khi 8987868546là một đầu vào hợp lệ, nó sẽ phá vỡ công cụ kiểm tra của bạn và cũng có rất nhiều (nếu không phải tất cả) các câu trả lời ...
Mischa

@MischaBehrend Ví dụ của bạn không phải là đầu vào hợp lệ. Tôi nghĩ rằng bạn đã sẩy thai trường hợp thử nghiệm cuối cùng của tôi. Đầu vào hợp lệ là 898786854, không 8987868546(bạn đã thêm một 6ở cuối)
Ông Xcoder

nvm ... nên đọc toàn bộ quy tắc đầu tiên ... để lại điều này ở đây để bạn biết tại sao tôi nghĩ nó hợp lệ: đó không phải là một lỗi ... Tôi đã thay đổi ý định để kiểm tra các tập lệnh này ... và đọc các quy tắc đó một đầu vào hợp lệ. Tổng của tất cả các chữ số trong 8987868546 không phải là 1 ( Quy tắc 1 đã gặp ) và 8987868546là số nguyên dương cao hơn 1 ( Quy tắc 2 đã gặp ).
Mischa

Câu trả lời:


6

05AB1E , 13 12 byte

[¼DSO‰0Kθ©#®

Hãy thử trực tuyến!

Giải trình

[               # 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 byte

-1 cảm ơn hoàn toàn
-1 nhờ có ông Xcoder
-4 nhờ reffu

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

Hãy thử trực tuyến!




1
57 byte Ngoài ra, lời xin lỗi của tôi đã đưa ra câu trả lời của riêng tôi lúc đầu. Nó có ý nghĩa hơn như một bình luận
reffu

5

Haskell, 85 78 byte

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

Lưu được 7 byte nhờ Bruce Forte.

Hãy thử trực tuyến.


Lưu thêm một số byte bằng cách sử dụng divModvà bỏ where: Thử trực tuyến!
Laikoni

@Laikoni Wow, đó là một sự cải tiến! Xin vui lòng gửi nó như là một câu trả lời khác nhau; Nó đủ khác với tôi. BTW: Tôi đang tìm kiếm một mẹo để thoát khỏi where. Tôi sẽ sử dụng điều này trong tương lai. :)
Cristian Lupascu

sum[read[d]|d<-show n]lưu một byte
nimi

5

JavaScript (ES6), 66 58 51 49 byte

Lấy đầu vào là một số nguyên. Lợi nhuận falsecho 0hay 1và ném một lỗi tràn bộ nhớ khi nó gặp bất kỳ số có chữ số thêm đến 1.

f=n=>n>1&&f(n%(x=eval([...""+n].join`+`))||n/x)+1
  • 8 byte được lưu với sự giúp đỡ từ Justin .

Kiểm tra nó

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
Bạn có thể lưu một số byte bằng cách tính tổng các chữ số bằng cách sử dụng eval(array.join`+`)?
Justin Mariner

Tôi thực sự có thể, @JustinMariner - bạn đã khiến tôi thích nó! Cảm ơn :)
Shaggy

4

Husk , 12 byte

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

Hãy thử trực tuyến!

Giải trình

←€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.



2

Võng mạc , 100 byte

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

Hãy thử trực tuyến! Liên kết chỉ bao gồm các trường hợp thử nghiệm nhỏ hơn vì những trường hợp lớn hơn mất quá nhiều thời gian.


2

Toán học, 73 byte

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

==0thể thay thế bằng <1?
Ông Xcoder

@ Mr.Xcoder có, tất nhiên! Tôi đã tạo một phiên bản sắp xếp ...
J42161217

2

PHP, 68 + 1 byte

đầu ra đơn nguyên:

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

đầu ra thập phân, 73 + 1 byte:

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

Chạy như ống với -nRhoặc thử trực tuyến .


Toán tử Elvis yêu cầu PHP 5.3 trở lên. Đối với PHP cũ hơn, thay thế ?:bằng ?$n%$s:(+5 byte).


2

Ruby, 46 byte

f=->n{s=n.digits.sum;n<2?0:1+f[n%s<1?n/s:n%s]}

2

Haskell , 94 93 89 88 byte

Cảm giác này thực sự dài ..

length.fst.span(/=1).iterate g
g x|(d,m)<-x`divMod`sum[read[d]|d<-show x]=last$m:[d|m<1]

Hãy thử trực tuyến!

Cảm ơn @Laikoni & @nimi vì đã chơi golf mỗi byte 1 byte!





1

Perl, 71 byte, 64 byte, 63 byte

-pl

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

Dùng thử trực tuyến

EDIT: đã lưu 7 byte, nhờ nhận xét của Xcali

-p

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

EDIT: kể từ 5.14 thay thế không phá hủy s /// r

-pl

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

-pltrên đầu được cho là một cờ dòng lệnh thay thế?
Erik the Outgolfer

vâng, chúng là những lựa chọn phù hợp
Nahuel Fouilleul

Bạn nên đếm -plcờ theo bài này .
Erik the Outgolfer

Tôi đếm 69 byte +2 cho các tùy chọn pl, có đúng không?
Nahuel Fouilleul

Bạn có thể chơi golf này xuống một chút. $ckhông cần phải được khởi tạo. Nó sẽ bắt đầu ở mức undef0. Dấu chấm phẩy sau khi đóng có thể đi. Ngoài ra, bạn không cần -l. Không bắt buộc phải có nhiều đầu vào trong một lần chạy.
Xcali

1

APL Dyalog, 36 byte

{x←+/⍎¨⍕⍵⋄1=⍵:00=x|⍵:1+∇⍵÷x1+∇x|⍵}

Hãy thử trực tuyến!

Làm sao?

{
   x←+/⍎¨⍕⍵       x = digit sum
   1=⍵:0          if arg = 1: bye
   0=x|⍵:1+∇⍵÷x   if arg divisible by x: recurse with arg/x
   1+∇x|⍵         recurse with arg mod x
}

1

Gaia , 13 byte

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

Hãy thử trực tuyến!

Giải trình

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

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

Đầu vào phải được cung cấp cho hàm dưới dạng chuỗi, chẳng hạn như X ('152').

Hàm hoạt động bằng cách lặp và tăng d. Cácx=y; dòng là cần thiết để tránh một lỗi của Matlab cố gắng để đọc và ghi đè lên một giá trị biến cùng một lúc, rõ ràng, đó là một cái mới đối với tôi.

Ung dung:

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


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.