두 개의 회문으로는 충분하지 않습니다


24

14241 과 같은 일부 숫자14241 는 10 진수의 회문입니다. 숫자를 역순으로 쓰면 같은 숫자가됩니다.

일부 숫자는 2 개의 회 문의 합입니다. 예를 들어, 110=88+22 또는 2380=939+1441 입니다.

다른 숫자의 경우 2 개의 회문으로는 충분하지 않습니다. 예를 들어 21은 2 개의 회 문의 합으로 쓸 수 없으며 최선의 방법은 3 : 21=11+9+1 입니다.

정수 입력을 n받아 n2 개의 회 문의 합으로 분해 될 수없는 수를 출력 하는 함수 또는 프로그램을 작성하십시오 . 이것은 OEIS A035137에 해당합니다 .

한 자릿수 (0 포함)는 회문입니다.

시퀀스에 대한 표준 규칙이 적용됩니다.

  • 입력 / 출력이 유연합니다
  • 0 또는 1 인덱싱을 사용할 수 있습니다
  • 당신은 nth 항, 첫번째 n항 또는 무한 시퀀스를 출력 할 수 있습니다

참고로 모든 정수 최대 3 개의 회 문의 합 으로 분해 될 수 있습니다 .

테스트 사례 (1 인덱스) :

1 -> 21
2 -> 32
10 -> 1031
16 -> 1061
40 -> 1103

이것은 코드 골프이므로 가장 짧은 대답이 이깁니다.


2
무한 출력도 시퀀스의 표준 옵션이 아닙니까?
관련없는 문자열

@UnrelatedString 예, 허용하겠습니다.
로빈 라이더


2
@Abigail 양의 정수가 주어지면 n시퀀스의 n 번째 멤버를 출력합니다. OEIS An? 유망한 소리 ...
발은

2
@Nit 새로운 OEIS 시퀀스를 a (n) = n 번째 OEIS 시퀀스로 정의하여 시퀀스를 생성하는 가장 골프화 된 젤리 함수보다 적은 문자로 표현할 수 있습니다.
agtoever

답변:


13

자바 스크립트 (ES6),  93 83 80  79 바이트

@tsh 덕분에 1 바이트 절약

인덱스 된 n 번째 항을 반환합니다 .

i=>eval("for(n=k=1;k=(a=[...k+[n-k]+k])+''!=a.reverse()?k-1||--i&&++n:++n;);n")

온라인으로 사용해보십시오!

방법?

n 주어지면 kn - k 가 회문이 되도록 1kn 이 있는지 테스트합니다 . 경우 우리는 그런를 찾을 수 있습니까 K를 한 후, Nknkkn 개의 회문의 합이있다.

여기서의 트릭 은 k , n - kk 의 연결로 구성된 단일 문자열을 테스트하여 knk 를 동시에 처리하는 것 입니다.knkk

예:

대한 n=2380 :

  • 우리는 결국 k=1441 도달 하고 n k = 939에 도달합니다nk=939
  • " 14419391441 " 문자열을 테스트하여 회문임을 확인합니다

댓글

주의 : 이것은 eval()가독성이 없는 버전 입니다.

i => {                       // i = index of requested term (1-based)
  for(                       // for loop:
    n = k = 1;               //   start with n = k = 1
    k =                      //   update k:
      ( a =                  //     split and save in a[] ...
        [...k + [n - k] + k] //     ... the concatenation of k, n-k and k
      ) + ''                 //     coerce it back to a string
      != a.reverse() ?       //     if it's different from a[] reversed:
        k - 1                //       decrement k; if the result is zero:
          || --i             //         decrement i; if the result is not zero:
            && ++n           //           increment n (and update k to n)
                             //         (otherwise, exit the for loop)
      :                      //     else:
        ++n;                 //       increment n (and update k to n)
  );                         // end of for
  return n                   // n is the requested term; return it
}                            //

i=>eval("for(n=k=1;k=(s=[...k+[n-k]+k])+''!=s.reverse()?k-1||i--&&++n:++n;);n")79 바이트
tsh

대신 i=>eval("...")ES6을 사용 i=>eval`...`하여 2 바이트를 절약 할 수 있습니다.
VFDan

또한 반환 값을 지정하지 않으면 eval의 기본값은 마지막으로 평가 된 식으로 설정되므로 ;n끝 부분을 제거 할 수 있습니다 .
VFDan

@VFDan 백틱 트릭은 eval()문자열에 대한 인수를 강제하지 않기 때문에 작동 하지 않습니다. 제거 ;n하면 구문 오류가 발생하고 제거 n하면 함수가 반환 undefined됩니다.
Arnauld

12

젤리 ,  16 10  9 바이트

Outgolfer Erik 덕분에 -1 바이트 . 처음 n 항을 출력합니다 .

2_ŒḂƇ⁺ṆƲ#

온라인으로 사용해보십시오!

나는 원래의 접근법과 다른 아이디어를 생각해 보았습니다. 사고 과정을 살펴 보자.

  • 처음에는 테스트가 다음과 같이 작동했습니다. 해당 숫자의 정수 파티션을 생성 한 다음 비 회문이 포함 된 파티션을 필터링 한 다음 길이 2의 적격 목록이 몇 개인 지 계산했습니다. 이것은 코드 길이면에서 너무 효율적이지 않았습니다.

  • N 의 정수 파티션을 생성 한 다음 필터링은 길이와 시간 효율성이라는 두 가지 주요 단점이있었습니다. 이 문제를 해결하기 위해 먼저 두 숫자가 회문이어야한다는 조건 으로 N (모두 임의의 길이 목록이 아님 )에 해당하는 정수 쌍 ( x , y ) 생성하는 방법을 생각해 낼 것이라고 생각 했습니다 .(x,y)N

  • 그러나 여전히, 나는 이것에 관한 "고전적인 방법"에 만족하지 않았습니다. 나는 접근법을 바꿨다 : 을 생성하는 대신 , 프로그램이 개성 회문에 중점을 두자 . 이 방법은, 하나는 단순히 모든 회문을 계산할 수 x 이하 N , 및 경우 Nx 도 회문되고, 우리는 완료됩니다.

코드 설명

2_ŒḂƇ⁺ṆƲ # – 모나 딕 링크 또는 전체 프로그램. 인수 : n.
2 # – 2에서 시작 * 하여 처음 만족하는 n 개의 정수를 찾으십시오.
 _ŒḂƇ⁺ṆƲ – ... 헬퍼 링크. 고장 (현재 정수 N이라고 부름) :
    Ƈ – 필터. 범위 [1 ... N]을 생성하고 그 범위 만 유지합니다 ...
  ŒḂ – ... 회문입니다. 예 : 21-> [1,2,3,4,5,6,7,8,9,11]
 _ – N에서 각 회문을 뺍니다. 예 : 21-> [20,19, ..., 12,10]
     ⁺ – 이전 링크를 복제합니다 (추가 링크가있는 것처럼 생각합니다)
            ⁺) 대신. 이 목록에는 회문 만 유지됩니다.
            리스트가 비어 있지 않다면, 우리는 쌍 (x, Nx)를 찾았 음을 의미합니다.
            두 개의 회문을 포함합니다 (그리고 분명히 x + Nx = N이므로 합은 N입니다).
      Ṇ – 논리 NOT (이 목록이 비어있는 정수를 찾고 있습니다).
       Ʋ – 마지막 4 개의 링크를 그룹화합니다 (기본적으로 _ŒḂƇ⁺Ṇ는 단일 모나드 역할을합니다).

* 그 문제에 대해서는 0이 아닌 다른 숫자가 작동합니다.


7

젤리 , 11 바이트

⁵ŻŒḂ€aṚ$EƲ#

온라인으로 사용해보십시오!

전체 프로그램은 대략 다음과 같이 작동합니다.

  1. z 를 입력으로 설정하십시오 .
  2. x10으로 설정하십시오 .
  3. R[]로 설정하십시오 .
  4. 0 에서 x 까지의 모든 정수 k에 대해 kx-k 가 모두 회 문형 인지 확인하십시오 .
  5. L의 모든 요소 가 동일하면 (즉, x에 합산 가능한 모든 쌍이 회문을 갖거나 모든 쌍이 대부분 회문을 갖는 경우) zz-1로 설정 하고 x를 추가합니다. 에 R .
  6. 만약 Z = 0 , 리턴 R 및 종료.
  7. xx + 1로 설정하십시오 .
  8. 4 단계로 이동하십시오.

5 단계가 실제로 작업을 수행하지 않는 것으로 의심 될 수 있습니다. x 에 합한 모든 쌍이 회 문형 인 경우 z를 실제로 줄이면 안됩니다 . 그러나 우리는 이것이 결코 일어나지 않을 것임을 증명할 수 있습니다.

먼저 정수를 고르자 케이 그래서 10케이엑스. 2 단계에서 x10으로 초기화하기 때문에 항상 그렇게 할 수 있습니다 .

만약 케이 회문이 아니에요 (케이,엑스케이)어디서 k+(xk)=x, therefore not all pairs have two palindromes.

If, on the other hand, k is a palindrome, then we can prove that k1 isn't a palindrome. Let the first and last digits of k be DF and DL respectively. Since k is a palindrome, DF=DL>0. Let the first and last digits of k1 be DF and DL respectively. Since DL>0, DL=DF1DF. Therefore, k1 isn't a palindrome, and we have the pair (k1,x(k1)), where (k1)+(x(k1))=k1+xk+1=x.

We conclude that, if we start with setting x to a value greater than or equal to 10, we can never have all pairs of non-negative integers that sum to x be pairs of palindromes.


Ah, beat me too it - first n terms saves 1 byte (I went for STDIN and ŻŒḂ€aṚ$Ṁ¬µ#
Jonathan Allan

@JonathanAllan Oh LOL didn't expect that. Anyway, somebody beat us both. :D
Erik the Outgolfer

For the proof, couldn't you just take the pair (10,x10), and use the fact that 10 is not a palindrome? Then the proof is one line.
Robin Ryder

@RobinRyder Yes, that's also possible. My proof is a generalization that contains this case as well (11 is a palindrome).
Erik the Outgolfer

3

Retina, 135 102 bytes

K`0
"$+"{0L$`\d+
*__
L$`
<$.'>$.`>
/<((.)*.?(?<-2>\2)*(?(2)$)>){2}/{0L$`\d+
*__
))L$`
<$.'>$.`>
0L`\d+

Try it online! Too slow for n of 10 or more. Explanation:

K`0

Start off by trying 0.

"$+"{

Repeat n times.

0L$`\d+
*__

Convert the current trial value to unary and increment it.

L$`
<$.'>$.`>

Create all pairs of non-negative integers that sum to the new trial value.

/<((.)*.?(?<-2>\2)*(?(2)$)>){2}/{

Repeat while there exists at least one pair containing two palindromic integers.

0L$`\d+
*__
))L$`
<$.'>$.`>

Increment and expand the trial value again.

0L`\d+

Extract the final value.


3

Haskell, 68 67 63 bytes

[n|n<-[1..],and[p a||p(n-a)|a<-[0..n]]]
p=((/=)=<<reverse).show

Returns an infinite sequence.

Collect all n where either a or n-a is not a palindrome for all a <- [0..n].

Try it online!


3

Perl 5 -MList::Util=any -p, 59 55 bytes

-3 bytes thanks to @NahuelFouilleul

++$\while(any{$\-reverse($\-$_)==reverse}0..$\)||--$_}{

Try it online!

Note: any could be replaced by grep and avoid the -M command line switch, but under the current scoring rules, that would cost one more byte.


small improvement, -3bytes, using while instead of redo
Nahuel Fouilleul

And took one more off of that by eliminating the + after the while.
Xcali

3

R, 115 111 bytes

-4 thanks to Giuseppe

function(n,r=0:(n*1e3))r[!r%in%outer(p<-r[Map(Reduce,c(x<-paste0),Map(rev,strsplit(a<-x(r),"")))==a],p,'+')][n]

Try it online!

Most of the work is packed into the function arguments to remove the {} for a multi-statement function call, and to reduce the brackets needed in defining the object r

Basic strategy is to find all palindromes up to a given bound (including 0), find all pairwise sums, and then take the n-th number not in that output.

The bound of n*1000 was chosen purely from an educated guess, so I encourage anyone proving/disproving it as a valid choice.

r=0:(n*1e3)can probably be improved with a more efficient bound.

Map(paste,Map(rev,strsplit(a,"")),collapse="")is ripped from Mark's answer here, and is just incredibly clever to me.

r[!r%in%outer(p,p,'+')][n]reads a little inefficient to me.


1
111 bytes just by rearranging a couple things.
Giuseppe


1

J, 57/60 bytes

0(](>:^:(1&e.p e.]-p=:(#~(-:|.)&":&>)&i.&>:)^:_)&>:)^:[~]

Try it online!

The linked version adds 3 bytes for a total of 60 in order to save as a function that the footer can call.

In the REPL, this is avoided by calling directly:

   0(](>:^:(1 e.q e.]-q=:(#~(-:|.)&":&>)&i.&>:)^:_)&>:)^:[~] 1 2 10 16 40
21 32 1031 1061 1103

Explanation

The general structure is that of this technique from an answer by Miles:

(s(]f)^:[~]) n
          ]  Gets n
 s           The first value in the sequence
         ~   Commute the argument order, n is LHS and s is RHS
        [    Gets n
      ^:     Nest n times with an initial argument s
  (]f)         Compute f s
         Returns (f^n) s

This saved a few bytes over my original looping technique, but since the core function is my first attempt at writing J, there is likely still a lot that can be improved.

0(](>:^:(1&e.p e.]-p=:(#~(-:|.)&":&>)&i.&>:)^:_)&>:)^:[~]
0(]                                                 ^:[~] NB. Zero as the first term switches to one-indexing and saves a byte.
   (>:^:(1&e.p e.]-p=:(#~(-:|.)&":&>)&i.&>:)^:_)&>:)      NB. Monolithic step function.
                                                 >:       NB. Increment to skip current value.
   (>:^: <predicate>                        ^:_)          NB. Increment current value as long as predicate holds.
                   p=:(#~(-:|.)&":&>)&i.&>:               NB. Reused: get palindromes in range [0,current value].
                       #~(-:|.)&":&>                      NB. Coerce to strings keeping those that match their reverse.
                 ]-p                                      NB. Subtract all palindromes in range [0,current value] from current value.
    >:^:(1&e.p e.]-p                                      NB. Increment if at least one of these differences is itself a palindrome.

That's an old format of mine, combining other tricks I learned since then produces a 41 char solution: 1&(_:1&((e.((*&(-:|.)&":"0>:)&i.-))+])+)*
miles

1

05AB1E, 15 12 bytes

°ÝDʒÂQ}ãOKIè

-3 bytes thanks to @Grimy.

0-indexed.
Very slow, so times out for most test cases.

Try it online or verify the first few cases by removing the .

Much faster previous 15 byter version:

µNÐLʒÂQ}-ʒÂQ}g_

1-indexed.

Try it online or output the first n values.

Explanation:

°Ý              # Create a list in the range [0, 10**input]
  D             # Duplicate this list
   ʒÂQ}         # Filter it to only keep palindromes
       ã        # Take the cartesian product with itself to create all possible pairs
        O       # Sum each pair
         K      # Remove all of these sums from the list we duplicated
          Iè    # Index the input-integer into it
                # (after which the result is output implicitly)

µ               # Loop until the counter variable is equal to the (implicit) input-integer
 NÐ             #  Push the loop-index three times
   L            #  Create a list in the range [1, N] with the last copy
    ʒÂQ}        #  Filter it to only keep palindromes
        -       #  Subtract each from N
         ʒÂQ}   #  Filter it again by palindromes
             g_ #  Check if the list is empty
                #   (and if it's truthy: increase the counter variable by 1 implicitly)
                # (after the loop: output the loop-index we triplicated implicitly as result)

1
12: °LDʒÂQ}ãOKIè (there's probably a better upper bound than 10^x for speed). I guess ∞DʒÂQ}ãOK is technically a 9, but it times out before the first output.
Grimmy

@Grimy Not sure if cartesian product works lazy-loaded on infinite lists. Anyway, as for the 12-byter, it's unfortunately incorrect. It does filter out integers that can be formed by summing 2 palindromes, but not integers that are palindromes themselves. Your sequence (without the trailing ) goes like: [1,21,32,43,54,65,76,87,98,111,131,141,151,...] but is supposed to go like [*,21,32,43,54,65,76,87,98,201,1031,1041,1051,1052,...] (the first 1/* can be ignored since we use 1-indexed input).
Kevin Cruijssen

1
@Grimy Hmm, I guess a straight-forward fix is changing the 1-based list L to 0-based.. :)
Kevin Cruijssen

0

Red, 142 bytes

func[n][i: 1 until[i: i + 1 r: on repeat k i[if all[(to""k)= reverse
to""k(s: to""i - k)= reverse copy s][r: off break]]if r[n: n - 1]n < 1]i]

Try it online!

Returns n-th term, 1-indexed


0

Python 3, 107 bytes

p=lambda n:str(n)!=str(n)[::-1]
def f(n):
 m=1
 while n:m+=1;n-=all(p(k)+p(m-k)for k in range(m))
 return m

Try it online!

Inverting the palindrome checking saved 2 bytes :)

For reference the straight forward positive check (109 bytes):

p=lambda n:str(n)==str(n)[::-1]
def f(n):
 m=1
 while n:m+=1;n-=1-any(p(k)*p(m-k)for k in range(m))
 return m

0

APL(NARS), 486 bytes

r←f w;p;i;c;P;m;j
p←{k≡⌽k←⍕⍵}⋄i←c←0⋄P←r←⍬
:while c<w
    i+←1
    :if   p i⋄P←P,i⋄:continue⋄:endif
    m←≢P⋄j←1
    :while j≤m
         :if 1=p i-j⊃P⋄:leave⋄:endif
         j+←1
    :endwhile
    :if j=m+1⋄c+←1⋄r←i⋄:endif
:endwhile

What is the word for break the loop? It seems it is ":leave", right? {k≡⌽k←⍕⍵} in p is the test for palindrome. This above function in the loop store all the palindrome found in the set P, if for some element w of P is such that i-w is in P too this means that the i is not right and we have increment i. Results:

  f 1
21
  f 2
32
  f 10
1031
  f 16
1061
  f 40
1103
  f 1000
4966
  f 1500
7536
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.