Chức năng nghịch đảo Colombia


28

Hãy xác định một chuỗi: Chuỗi tổng hợp n chữ số (n-DSS) là một chuỗi bắt đầu bằng n . Nếu số cuối cùng là k , thì số tiếp theo là k + chữ số-tổng (k) . Dưới đây là một vài n-DSS đầu tiên:

1-DSS: 1, 2, 4, 8, 16, 23, 28, 38, 49, 62, 70...
2-DSS: 2, 4, 8, 16, 23, 28, 38, 49, 62, 70, 77...
3-DSS: 3, 6, 12, 15, 21, 24, 30, 33, 39, 51, 57...
4-DSS: 4, 8, 16, 23, 28, 38, 49, 62, 70, 77, 91...
5-DSS: 5, 10, 11, 13, 17, 25, 32, 37, 47, 58, 71...
6-DSS: 6, 12, 15, 21, 24, 30, 33, 39, 51, 57, 69...
7-DSS: 7, 14, 19, 29, 40, 44, 52, 59, 73, 83, 94...
8-DSS: 8, 16, 23, 28, 38, 49, 62, 70, 77, 91, 101...
9-DSS: 9, 18, 27, 36, 45, 54, 63, 72, 81, 90, 99...

Đối với 1, đây là A004207 , mặc dù một vài chữ số đầu tiên khác nhau do định nghĩa hơi khác nhau. Đối với 3, đó là A016052 ; cho 9, A016096 .

Thử thách ngày nay là tìm ra chuỗi tổng n chữ số thấp nhất mà một số đã cho xuất hiện. Đây được gọi là "Hàm nghịch đảo Colombia" và là A036233 . Hai mươi điều khoản đầu tiên, bắt đầu bằng 1 là:

1, 1, 3, 1, 5, 3, 7, 1, 9, 5, 5, 3, 5, 7, 3, 1, 5, 9, 7, 20

Một số trường hợp kiểm tra tốt khác:

117: 9
1008: 918

Bạn chỉ phải xử lý các số nguyên lớn hơn 0 và bạn có thể nhận đầu vào và đầu ra ở bất kỳ định dạng tiêu chuẩn nào. Như thường lệ, đây là , vì vậy câu trả lời ngắn nhất trong mỗi ngôn ngữ sẽ thắng.


Câu trả lời:


12

Haskell , 104 64 63 byte

(-26 cảm ơn H.PWiz, thêm -14 nhờ Sriotchilism O'Z cổ, thêm -1 nhờ vào cole)

Đây là một chức năng.

f x=[y|y<-[1..],x==until(>=x)(foldr((+).read.pure)<*>show)y]!!0

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


Giải trình:

(foldr((+).read.pure)<*>show)

Trình tự các hàm tổng hợp trả về y + tổng kỹ thuật số của y. Chuyển đổi thành chuỗi đầu tiên, sau đó thực hiện một số môn thể dục đơn nguyên để có được tổng của các ký tự và số gốc (nhờ Cole).

Các <*>nhà điều hành trong bối cảnh này có kiểu và định nghĩa

(<*>) :: (a -> b -> c) -> (a -> b) -> c
f <*> g = \x -> f x (g x)

vì vậy chúng ta có thể viết như trên

\x -> foldr ((+) . read . pure) x (show x)

Điều này read . purechuyển đổi một Charthành một số, vì vậy (+) . read . pure :: Char -> Int -> Intthêm một chữ số vào một giá trị tích lũy. Giá trị này được khởi tạo cho số đã cho trong lần.

until (>=x) {- digital sum function -} y

untilliên tục áp dụng một hàm cho kết quả của nó (trong trường hợp này là y + tổng y) cho đến khi nó đáp ứng một yêu cầu được chỉ định bởi một hàm trong đối số đầu tiên. Điều này cho phần tử y-DSS nhỏ nhất lớn hơn hoặc bằng x.

[y | y<-[1..]; x == {- smallest y-DSS element >= x -} ]

Danh sách lười biếng vô hạn của y sao cho phần tử y-DSS nhỏ nhất> = x thực sự là x. Sử dụng ký hiệu hiểu danh sách của Haskell (mà tôi cũng hoàn toàn quên mất, cảm ơn bạn).

f x = {- aforementioned list -} !! 0

Yếu tố đầu tiên của danh sách đó, là y nhỏ nhất thỏa mãn yêu cầu của thử thách.


1
Đây là cách tôi chơi golf.
H.PWiz

1
@ H.PWiz Cái này có giống nhau không? Tôi sẽ nghĩ như vậy nhưng việc sử dụng của bạn fmapở nơi đầu tiên làm tôi bối rối một chút.
Phù thủy lúa mì

1
OK nó đã mất rất nhiều fenangling nhưng tôi đã lạm dụng đơn vị độc giả để cạo đi một byte. Woohoo mã miễn phí! TIO
cole

@ SriotchilismO'Z cổ Cool. Tôi chỉ đánh golf một cách máy móc mà không nghĩ về nó
H.PWiz

1
Không chắc chắn làm thế nào để chỉnh sửa yêu cầu trên thiết bị di động, vì vậy tôi chỉ chỉnh sửa trong phần giải thích mã của mình - thoải mái thay đổi hoặc khôi phục.
cole


4

Perl 6 , 44 byte

->\a{+(1...{a∈($_,{$_+.comb.sum}...*>a)})}

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

Giải pháp ngây thơ kiểm tra mọi chuỗi cho đến khi tìm thấy một chuỗi có chứa đầu vào

Giải trình:

->\a{                                    }  # Anonymous code block taking input as a
     +(1...{                           })   # Find the first number
            a∈(                       )     # Where the input is an element of
                                ...         # The sequence
               $_,                          # Starting with the current number
                  {            }   # Where each element is
                   $_+             # Is the previous element plus
                      .comb.sum    # The digit sum
                                   *>a      # Until the element is larger than the input



3

MATL , 18 byte

`@G:"ttFYAs+]vG-}@

Hãy thử trực tuyến! Hoặc xác minh 20 giá trị đầu tiên .

Giải trình

Đối với đầu vào i, điều này tiếp tục duy trì ncho đến khi các iđiều khoản đầu tiên của nchuỗi -th bao gồm i. Nó là đủ để kiểm tra icác điều khoản cho mỗi trình tự vì trình tự đang tăng lên.

`         % Do...while
  @       %   Push iteration index, n. This is the firsrt term of the n-th sequence
  G:      %   Push [1 2 ... i], where i is the input
  "       %   For each (i.e., do the following i times)
    tt    %     Duplicate twice
    FYA   %     Convert to digits
    s     %     Sum
    +     %     Add to previous term. This produces a new term of the n-th sequence
  ]       %   End
  v       %   Concatenate all terms into a column vector
  G-      %   Subtract i, element-wise. This is the do...while loop condition (*).
}         % Finally (this is executed right before exiting the loop)
  @       %   Push current n. This is the output, to be displayed
          % End (implicit). A new iteration will start if all terms of (*) are nonzero
          % Display (implicit)

3

Forth (gforth) , 106 byte

: f
>r 0 begin 1+ dup begin dup i < while dup begin 10 /mod >r + r> ?dup 0= until repeat i = until rdrop
;

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

Giải thích mã

: f                \ start a new word definition
  >r               \ store the input on the return stack for easy access
  0                \ set up a counter
  begin            \ start an indefinite loop
    1+ dup         \ add 1 to the counter and duplicate
    begin          \ start a 2nd indefinite loop
      dup i <      \ check if current value is less than the input value
    while          \ if it is, continue with the inner loop
      dup          \ duplicate the current value
      begin        \ innermost loop, used to get the digit-wise sum of a number
        10 /mod    \ get quotient and remainder of dividing by 10
        >r + r>    \ add remainder to current list value
        ?dup 0=    \ check if quotient is 0
      until        \ end the innermost loop if it is
    repeat         \ go back to the beginning of the 2nd loop
    i =            \ check if the "last" value of the current list = the input value
  until            \ if it does, we're done
  rdrop            \ remove the input value from the return stack
;                  \ end the word definition    

3

Bình thường , 13 byte

fqQ.W<HQ+ssM`

Hãy thử nó ở đây hoặc kiểm tra thử nghiệm .


Làm thế nào nó hoạt động

fqQ.W<HQ+ssM`     Full program. Takes input Q from STDIN, writes to STDOUT.
f{...}            Loop over 1,2,3,... and find the first number to yield truthy results when
                     applying the function {...} (whose variable is T = the current integer).
 qQ.W<HQ+ssM`     The function {...}, which will be analysed separately.
   .W             Functional while. While condition A is true, do B.
     <HQ          Cond. A (var: H - starts at T): Checks if H is less than Q.
        +ssM`     Func. B (var: G - G & H are the same): If A, G & H become G+digit sum(G)
                  The last value of this functional while will be the least possible number N
                  in the T-DSS that is greater than or equal to Q.
                  If N = Q, then Q ∈ T-DSS. Else (if N > Q), then Q ∉ T-DSS.
 q                That being said, check whether N == Q. 

nk1nnnk


1
Hoàn thành tốt, tôi đã có fqQ.W<HQ+sjZ10 14. Tôi tiếp tục quên đi `và s như một cách để lấy các chữ số từ một số nguyên!
Sok

3

Thạch , 9 byte

DS+)i$ƬṖṪ

Một liên kết đơn nguyên chấp nhận một số nguyên dương nmang lại một số nguyên dương a(n), là nghịch đảo Colombia của n.

Hãy thử trực tuyến! Hoặc xem bộ thử nghiệm .

Làm sao

Thực tế, chúng tôi làm việc ngược lại, liên tục tìm kiếm giá trị mà chúng tôi đã thêm vào cho đến khi chúng tôi không thể tìm thấy giá trị:

DS+)i$ƬṖṪ - Link: integer n
      Ƭ   - Repeat until a fixed point, collecting up:
     $    -   last two links as a monad - f(n):
   )      -     left links as a monad for each - [g(x) for x in [1..n]]:
D         -       decimal digits of x
 S        -       sum
  +       -       add x
    i     -     first (1-indexed) index of n in that list, or 0 if no found
       Ṗ  - pop of the rightmost value (the zero)
        Ṫ - tail

Lấy 13ví dụ ...

D  )  = [[1],[2],[3],[4],[5],[6],[7],[8],[9],[1,0],[1,1],[1,2],[1,3]]
 S    = [  1,  2,  3,  4,  5,  6,  7,  8,  9,    1,    2,    3,    4]
  +   = [  2,  4,  6,  8, 10, 12, 14, 16, 18,   11,   13,   15,   17]
    i 13 = .......................................... 11
    i 11 = .................................... 10
    i 10 = ............... 5
    i 5 = not found = 0 
    i 0 = not found = 0
    Ƭ -> [13, 11, 10, 5, 0]
    Ṗ =  [13, 11, 10, 5]
    Ṫ =               5

2

Con trăn 2 , 85 byte

f=lambda n,a=[]:n in a and a.index(n)or f(n,[k+sum(map(int,`k`))for k in a]+[len(a)])

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

Điều này chắc chắn hoạt động cho tất cả các trường hợp thử nghiệm, cộng với tất cả các mục 1..88 được đưa ra tại OEIS; nhưng tôi vẫn không chắc chắn nó có thể chứng minh chính xác. (Đây là một trong những khiếu nại của tôi liên quan đến Nhà thờ Thử nghiệm Đơn vị :)).


d(x)xCtôi(S)tôiSCtôi(0)= =tôi;Ctôi(S)= =Ctôi(S-1)+Σd(Ctôi(S-1))x>1ed(x)(e1)ed(x)(e0)Σd(x)1

S(tôi)Ctôi(S(tôi))= =nΣd(Ctôi(S-1))1tôi<tôi'nS(tôi),S(tôi')S(tôi')-S(tôi)tôi'-tôitôintôia.index(n)

@Value Ink: Roger! Điều đó hoàn toàn hoạt động. Cảm ơn!
Chas Brown


2

MathGolf , 13 byte

╒môk(É∙Σ+=k/)

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

Thử thách lớn! Nó khiến tôi tìm thấy một vài lỗi trong hành vi pop ẩn của MathGolf, đã thêm 1-2 byte vào giải pháp.

3

╒               range(1,n+1) ([1, 2, 3])
 mô             explicit map using 6 operators
   k(           push input-1 to TOS
     É          start block of length 3 (repeat input-1 times)
      ∙Σ+       triplicate TOS, take digit sum of top copy, and add that to second copy
                This transforms the array items to their respective sequences instead
                Array is now [1, 2, 4, 2, 4, 8, 3, 6, 12]
         =      get index of element in array (the index of 3 is 6)
          k/    divide by input (gives 2)
            )   increment (gives the correct answer 3)

Để chứng minh rằng điều này sẽ luôn hoạt động, thật dễ dàng để thấy điều đó n <= input, bởi vì inputlà yếu tố đầu tiên của inputchuỗi thứ. Về mặt kỹ thuật tôi đã không chứng minh rằng giải pháp này luôn hợp lệ, nhưng nó vượt qua mọi trường hợp thử nghiệm mà tôi đã thử nghiệm.



1

Sạch , 86 byte

import StdEnv
$n=hd[i\\i<-[1..]|n==while((>)n)(\j=j+sum[toInt d-48\\d<-:toString j])i]

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

Mở rộng:

$ n                    // function `$` of `n` is
 = hd [                // the first
   i                   // integer `i`
  \\                   // for
   i <- [1..]          // each integer from 1 upwards
  |                    // where 
   n ==                // `n` is equal to
   while ((>) n) (     // the highest value not more than `n` from
    \j = j + sum [     // `j` plus the sum of
      toInt d - 48     // the digital value
     \\                // for each
      d <-: toString j // digit in the string form of `j`
     ]                 // where `j` is the previous term
    )                  // of the sequence
   i                   // starting with term `i`
  ]

Nó làm phiền tôi digitToInt dlâu hơntoInt d-48





1

Japt , 15 14 byte

Các ternary để xử lý các trường hợp input=outputgây phiền nhiễu cho tôi!

@Ç?X±ìx:XÃøU}a

Thử nó

@Ç?X±ìx:XÃøU}a     :Implicit input of integer U
@                  :A function taking an integer X as its argument
 Ç                 :  Map each Z in the range [0,U)
  ?                :    If Z>0
   X±              :      Increment X by
     ì             :      Convert X to digit array
      x            :      Reduce by addition
       :X          :    Else X
         Ã         :  End map
          øU       :  Contains U
            }      :End function
             a     :Return the first integer that returns true when passed through that function

1

cQuents , 18 byte

#|1:#bN;A
=A?Z+UDZ

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

Giải trình

=A?Z+UDZ      second line - helper function
               first input = A
               second input = n
=A            first term is A
  ?           mode=query, return true if n in sequence, false if n not in sequence
              each term in the sequence equals
   Z+          previous term +
     U   )                     sum (                          )
      D )                            digits (               )
       Z                                      previous term

#|1:#bN;A     main program
               first input = A  (user input)
               second input = n
#|1           n = 1
   :          mode=sequence, return the nth term in the sequence
    #     )   conditional - next term equals next N that evaluates to true
              N increments, any terms that evaluate to true are added to the sequence
               conditional (                      )
     b   )                   second line (      )
      N;A                                  N, A

1

Forth (gforth) , 99 byte

: f >r 0 begin 1+ dup begin dup i < while dup 20 for 10 /mod >r + r> next + repeat i = until r> . ;

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

Phần lớn tương tự như đệ trình của reffu (106 byte) . Các bộ phận của golf là:

  • Tính toán tổng số (-6)
  • Dọn dẹp cuối cùng (-1) bằng cách in một số rác thành thiết bị xuất chuẩn. (Không có vấn đề gì vì kết quả được trả về trên cùng của ngăn xếp.)

Làm thế nào nó hoạt động

: dsum ( n -- n+digitsum ) \ Sub-function. Given n, add its digit sum to n.
  dup                      \ Copy n to form ( n m ) -> extract digits from m and add to n
  20 for                   \ Repeat 20 times (a 64-bit int is at most 20 digits)
    10 /mod >r + r>        \   n += m%10, m = m/10
  next + ;                 \ End loop and discard 0

: f ( n -- ans )    \ Main function.
  >r                \ Move n to the return stack, so it can be referenced using `i`
  0 begin 1+        \ Initialize counter and loop starting from 1
    dup begin       \   Copy the counter (v) and loop
      dup i < while \     break if v >= n
      dsum          \     v += digit sum of v
    repeat          \   End loop
  i = until         \ End loop if n == v
  r> . ;            \ Cleanup the return stack so the function can return correctly
                    \ `r> .` is one byte shorter than `rdrop`

0

Than , 26 byte

NθW¬№υθ«UMυ⁺κΣκ⊞υ⊕Lυ»I⊕⌕υθ

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Sử dụng thuật toán của @ ChasBrown. Nếu điều đó không hợp lệ, thì với 29 byte:

NθW¬№υθ«≔⊕LυηW‹ηθ≧⁺Σηη⊞υη»ILυ

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Hoạt động bằng cách tính toán thành viên đầu tiên của mỗi chuỗi tổng hợp chữ số không nhỏ hơn n. Giải trình:

Nθ

Đầu vào n.

W¬№υθ«

Lặp lại cho đến khi chúng ta tìm thấy một chuỗi tổng hợp chữ số có chứa n.

≔⊕Lυη

Trình tự tiếp theo bắt đầu với một nhiều hơn số lượng trình tự cho đến nay.

W‹ηθ

Vòng lặp trong khi thành viên của chuỗi nhỏ hơn n.

≧⁺Σηη

Thêm tổng chữ số để có được thành viên tiếp theo của chuỗi.

⊞υη

Đẩy thành viên cuối cùng vào danh sách.

»ILυ

In số lượng danh sách được tính toán cho đến khi chúng tôi tìm thấy một danh sách có chứa n.




0

Gaia , 16 byte

1⟨⟨:@<⟩⟨:Σ+⟩↺=⟩#

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

Trả về một danh sách chứa số nguyên nhỏ nhất.

1⟨	      ⟩#	% find the first 1 positive integers where the following is truthy:
	     =		% DSS equal to the input?
  	    ↺		% while
  ⟨:@<⟩			% is less than the input
       ⟨:Σ+⟩		% add the digital sum to the counter

Gaia , 16 byte

1⟨w@⟨:):Σ++⟩ₓĖ⟩#

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

Sử dụng các quan sát được thực hiện bởi ông Xcoder . Nó không ngắn hơn cái kia, nhưng dù sao nó cũng là một cách tiếp cận thú vị.

1⟨	      ⟩#	% find the first 1 integers z where:
  	     Ė		% the input (n) is an element of
  w@⟨:):Σ++⟩ₓ		% the first n terms of the z-th Digital Sum Sequence

Gaia , 16 byte

┅ẋ⟨@⟨:):Σ++⟩ₓĖ⟩∆

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

Cách tiếp cận thứ ba không sử dụng N-find, #nhưng vẫn dựa vào quan sát tương tự như cách tiếp cận giữa. Trả về một số nguyên chứ không phải là một danh sách.


0

Clojure , 106 byte

#(loop[j 1 i 1](if(= j %)i(if(< j %)(recur(apply + j(for[c(str j)](-(int c)48)))i)(recur(inc i)(inc i)))))

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

Đây là 99 byte nhưng kết quả là Stack Overflow trên các đầu vào lớn hơn (có thể điều chỉnh JVM sẽ giúp ích):

#((fn f[j i](if(= j %)i(if(< j %)(f(apply + j(for[c(str j)](-(int c)48)))i)(f(inc i)(inc i)))))1 1)



0

mực , 130 127 byte

-(l)
+(i)[+]->l
*(w)[{i}]
~temp n=w
-(o){n<i:
~n+=s(n)
->o
}{n>i:->w}{w}
==function s(n)
{n>9:
~return n%10+s(n/10)
}
~return n

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

  • -3 bytes bằng cách chuyển đổi thành một chương trình đầy đủ có đầu vào đơn nguyên.

Điều này cảm thấy quá lâu để không thể chơi golf.

Bị đánh cắp

// This program takes unary input. It passes through the same choice prompt as long as it recieves 1, and execution begins when it recieves 2
-(input_loop)
+(input_value)[+] -> input_loop                 // When this option (option 1) is selected, its read count is incremented. We can access this via the "input_value" variable. We then return to the prompt by going back to the "input_loop" gather
*(which_sequence)[{i}]                          // When this option (option 2) is selected, execution begins. Its read count also serves to keep track of which DSS we're checking.
~temp current_value = which_sequence            // The initial value for the n-DSS is n, of course.
-(sequence)                                     //
{current_value < input_value:                   // If we're still below the value we're looking for, we might find it.
    ~ current_value += digit_sum(current_value) // To get the next number, we add the current number's digit sum
    -> sequence                                 // Then we loop
}
{n > i: -> which_sequence}                      // If we get here, we're at or above our target number. If we're above it, we know it's the wrong sequence and move on to the next one by going back up to option 2. This increments its read count.
{which_sequence}                                // If we get here, we've found the target number, so we output the sequence's number.
// End of main stitch, program ends.

// A function to calculate the digit sum of a number
== function digit_sum(n) ==
{n > 9: // If given a number greater than 9, recurse
    ~ return (n % 10) + digit_sum(n / 10)
}
~ return n // Otherwise, return the input (it's a single digit)

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.