Mã hóa một số nguyên


33

Cho số nguyên dương n > 2. Chúng tôi chuyển đổi nó thành một mảng như sau:

  1. Nếu nó bằng 2trả về một mảng trống
  2. Mặt khác, tạo mảng của tất cả ncác thừa số nguyên tố được sắp xếp tăng dần, sau đó mỗi phần tử thay thế bằng chỉ mục của nó trong chuỗi số nguyên tố và cuối cùng chuyển đổi từng phần tử thành mảng

Ví dụ, cho phép chuyển đổi số 46thành mảng. Đầu tiên, chuyển đổi nó thành mảng các yếu tố chính của nó:

[2, 23]

Số 239số nguyên tố, vì vậy thay thế 2bằng mảng trống và 23bằng [9]. Mảng bây giờ trở thành:

[[], [9]]

Thừa số nguyên tố của 933, vì vậy:

[[], [3, 3]]

Làm tương tự cho cả hai 3:

[[], [[2], [2]]]

Và cuối cùng:

[[], [[[]], [[]]]]

Bây giờ, để mã hóa nó, chúng ta chỉ cần thay thế từng khung mở bằng 1và mỗi khung đóng bằng 0, sau đó loại bỏ tất cả các số 0 kết thúc và thả một 1từ cuối. Đây là số nhị phân của chúng tôi. Sử dụng ví dụ trên:

[ ] [ [ [ ] ] [ [ ] ] ]

| | | | | | | | | | | |
| | | | | | | | | | | |
V V V V V V V V V V V V

1 0 1 1 1 0 0 1 1 0 0 0

Bây giờ chỉ cần thả ba số không cuối cùng và số cuối cùng 1. Số trở nên 10111001đó là 185trong hệ thập phân. Đó là sản lượng dự kiến. Lưu ý rằng không bao gồm trong khung chuyển đổi sang mảng nhị phân của mảng chính.

Đầu vào

Số nguyên dương nlớn hơn 2.

Đầu ra

Số nguyên được mã hóa n.

Định dạng quy tắc và IO

  • Quy tắc tiêu chuẩn áp dụng.
  • Đầu vào có thể là chuỗi hoặc số (nhưng trong trường hợp chuỗi phải ở cơ sở 10).
  • Đầu ra có thể là chuỗi hoặc số (nhưng trong trường hợp chuỗi phải ở cơ sở 10).
  • Đây là , câu trả lời ngắn nhất trong byte thắng!

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

Nhiều trường hợp thử nghiệm theo yêu cầu.

3 ---> 1
4 ---> 2
5 ---> 3
6 ---> 5
7 ---> 6
8 ---> 10
9 ---> 25
10 ---> 11
10000 ---> 179189987
10001 ---> 944359
10002 ---> 183722
10003 ---> 216499
10004 ---> 2863321
10005 ---> 27030299
10006 ---> 93754
10007 ---> 223005
10008 ---> 1402478

Hộp cát


Bạn nên loại bỏ trường hợp thử nghiệm 2vì các bài nộp không bắt buộc phải xử lý nó.
Ông Xcoder

4
Rip ngôn ngữ không có tích hợp sẵn.
Ông Xcoder

3
@Paul. "[...] Tạo mảng gồm tất cả các yếu tố chính của n được sắp xếp tăng dần"

1
@Quelklef. Tôi đang làm việc để thực hiện ATP (chỉ để cho vui, không có gì nghiêm trọng) và tôi đã cố gắng đại diện cho mọi số bằng cách sử dụng các mảng lồng nhau. Vì vậy, mã hóa này là ý tưởng đầu tiên tôi nghĩ ra.

1
@WheatWizard. Tôi không có nghĩa là ý nghĩa toán học chính xác của số nguyên từ . Tôi sẽ rời khỏi nó. :-)

Câu trả lời:


12

Husk , 35 31 30 29 26 25 24 22 20 19 15 byte

-7 byte nhờ @Zgarb!

Lưu thêm 4 byte, gián tiếp, nhờ vào Zgarb

ḋhΣhgφṁȯ`Jḋ2⁰ṗp

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

Giải thích

     φ             -- Define a recursive function which calls itself ⁰ and is applied to an Integer
      ṁ       p    -- map then concatenate over its prime factors
             ṗ     --   return their indices into the primes
            ⁰      --   and then recur, applying ⁰ to that number
       ȯ`Jḋ2       --   then surround it between the list [1,0] (binary 2)
    g              -- group adjacent equal elements
   h               -- drop last element (trailing 0s)
  Σ                -- concatenate
 h                 -- drop the last element
ḋ                  -- interpret as base 2

Tôi nghĩ rằng sẽ hoạt động với 27 byte, nhưng TIO hết thời gian trong khi suy luận kiểu ...
Zgarb

2
Đừng bận tâm, 25 byte và làm việc. Cuối cùng là một trường hợp sử dụng cho φ, lambda fixpoint!
Zgarb

Ồ, tôi chưa bao giờ thực sự hiểu trường hợp sử dụng của nó, cho đến bây giờ
H.PWiz

Chúng tôi đã thêm lambdas fixpoint vào Husk từ rất sớm, trước khi các chương trình đa dòng được triển khai. Tôi đoán chúng tôi nghĩ rằng họ sẽ là cách tốt nhất để xử lý đệ quy. Nhưng chúng khá mơ hồ ngoài việc tiết kiệm một byte trong những trường hợp đặc biệt như thế này.
Zgarb

`:0:1có thể `Jḋ2.
Zgarb

7

Thạch ,  22 20  19 byte

-1 nhờ Erik the Outgolfer (số 0 ở hai bên t, thay vì từ bên phải œr)

ÆfÆC$ÐLŒṘO%3ḟ2Ḋt0ṖḄ

Một liên kết đơn âm lấy một số nguyên lớn hơn 2 và trả về một số nguyên lớn hơn 0 (2 cũng sẽ trả về 0 theo thông số ban đầu).

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

Làm sao?

Điều này gần như sao chép chính xác mô tả đã cho, chỉ với một số thao tác thông thường để tạo mảng nhị phân ...

ÆfÆC$ÐLŒṘO%3ḟ2Ḋt0ṖḄ - Link: number n (>=2)
     ÐL             - loop until no more changes occur:
    $               -   last two links as a monad:
Æf                  -     prime factorisation (includes duplicates & vectorises)
  ÆC                -     count primes less than or equal (vectorises)
                    -   ...note for entries of 2 this yields [1]
                    -      then for entries of 1 it yields [], as required
       ŒṘ           - get a Python representation - just like in the OP,
                    -    something like: "[[], [[[]], [[]]]]" (for an input of 46)
         O          - convert to ordinals e.g. [91,91,93,44,32,91,91,91,93,93,44,32,91,91,93,93,93,93]
          %3        - modulo by 3         e.g. [ 1, 1, 0, 2, 2, 1, 1, 1, 0, 0, 2, 2, 1, 1, 0, 0, 0, 0]
            ḟ2      - filter discard twos e.g. [ 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0]
              Ḋ     - dequeue             e.g. [ 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0]
               t0   - strip zeros         e.g. [ 1, 0, 1, 1, 1, 0, 0, 1, 1]
                 Ṗ  - pop                 e.g. [ 1, 0, 1, 1, 1, 0, 0, 1]
                  Ḅ - binary to decimal   e.g. 185

À, vâng, tôi chắc chắn có thể; cảm ơn.
Jonathan Allan

6

Python 2 , 212 177 byte

lambda n:int(g(n).rstrip("0")[1:-1],2)
g=lambda n:"1%s0"%"".join(map(g,p(n)))
def p(n,i=0,j=1):
 while n>1:
  j+=1;P=q=1;exec"P*=q*q;q+=1;"*~-j;i+=P%q
  while n%j<1:yield i;n/=j

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

Việc thiếu các hàm dựng sẵn thực sự làm tổn hại đến số byte và nó xuất hiện trên TIO với các số nguyên tố lớn hơn. Sử dụng kiểm tra tính nguyên thủy của xnor .


Python 2 + gmpy2 , 175 byte

lambda n:int(g(n).rstrip("0")[1:-1],2)
g=lambda n:"1%s0"%"".join(map(g,p(n)))
def p(n,i=0,j=1):
 while n>1:
  j+=1;i+=is_prime(j)
  while n%j<1:yield i;n/=j
from gmpy2 import*

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

Phiên bản này không hết thời gian cho các trường hợp thử nghiệm lớn hơn (ví dụ 10000 - 10008).


5

Toán học, 125 119 byte

Flatten[#//.{{1}->{1,0},a_/;a>1:>{1,List/@PrimePi[Join@@Table@@@FactorInteger@a],0}}]/.{1,d__,1,0..}:>{d}~FromDigits~2&

Sử dụng một cách tiếp cận hơi khác nhau; chuyển đổi các chỉ số chính thành {1, index, 0}và 2 thành {1, 0}.

Dùng thử trên Wolfram Sandbox

Sử dụng:

f = Flatten[ ...

f[10008]

1402478


Câu trả lời gốc hoạt động trên 10008, nhưng câu trả lời này không thành công
Kelly Lowder

1
@KellyLowder Đã sửa!
JungHwan Min


2

J, 74 73 66 byte

3 :'#.(}.~ >:@i.&1)&.|.2+}.;<@(_2,~_1,[:>:[:_1&p:q:) ::<"0@;^:_ y'

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

Đây là một mớ hỗn độn thực sự mà chắc chắn là cần phải chơi gôn thêm (ví dụ như loại bỏ định nghĩa hàm rõ ràng). Tôi nghĩ rằng quyền anh tôi đang làm đặc biệt là những gì mang lại cho người chơi bởi vì tôi thực sự không biết tôi đang làm gì ở đó (đó là rất nhiều thử nghiệm và sai sót). Ngoài ra, tôi khá chắc chắn rằng có một số tích hợp mà tôi đã quên (ví dụ: tôi cảm thấy _2,~_1,có lẽ có tích hợp sẵn).

Giải thích (vô danh)

Lời nói đầu

Ngồi lại thật chặt, bởi vì đây sẽ không phải là một lời giải thích ngắn. Trớ trêu thay, một ngôn ngữ ngắn gọn đã được ghép nối với một người dài dòng.

Tôi sẽ chia nó thành một vài chức năng

encode  =. 3 : '<@(_2,~_1, [: >: [: _1&p: q:) ::<"0@;^:_ y'
convert =. 3 : '2 + }. ; y'
drop    =. (}.~ >:@i.&1)&.|.
decode  =. #.
  • encode mã hóa số nguyên bằng cách sử dụng _1 và _2 thay vì [và]
  • convert chuyển đổi danh sách _1 và _2 thành danh sách 1 và 0
  • drop giảm 1 số cuối và số 0
  • decode chuyển đổi từ danh sách nhị phân thành số

Tôi sẽ thực hiện một cuộc gọi mẫu cho 46, được thể hiện ở định dạng không được thực hiện

   decode drop convert encode 46
185

Mã hóa

Có rất nhiều điều để giải thích ở đây.

3 : '<@(_2,~_1, [: >: [: _1&p: q:) ::< "0@;^:_ y'
                                           ^:_      Do until result converges
                                          ;          Raze (remove all boxing)
                                       "0            For each
                               q:                     Factorize
                         _1&p:                        Get index of prime
                   >:                                 Add 1 (J zero-indexes)
            _1,                                       Prepend -1
        _2,~                                          Append -2
     <                                                Box resulting array
                                   ::                If there is an error
                                     <                Box the element

Lưu ý rằng định nghĩa hàm rõ ràng 3 : '[function]'đánh giá hàm như thể nó nằm trên REPL với đối số đúng thay thế mọi trường hợp của y(điều này có nghĩa là tôi có thể tránh phải sử dụng caps ( [:), atops ( @) và ats ( @:) với chi phí một vài byte).

Đây là những gì nó trông giống như cho mỗi lần lặp lại liên tiếp trên đầu vào của 46

┌─────────┐    ┌──┬─────┬─────────┬──┐    ┌──┬──┬──┬──┬───────┬───────┬──┬──┐
│_1 1 9 _2│ => │_1│_1 _2│_1 2 2 _2│_2│ => │_1│_1│_2│_1│_1 1 _2│_1 1 _2│_2│_2│ =>
└─────────┘    └──┴─────┴─────────┴──┘    └──┴──┴──┴──┴───────┴───────┴──┴──┘

┌──┬──┬──┬──┬──┬─────┬──┬──┬─────┬──┬──┬──┐    
│_1│_1│_2│_1│_1│_1 _2│_2│_1│_1 _2│_2│_2│_2│ => the final iteration is just every
└──┴──┴──┴──┴──┴─────┴──┴──┴─────┴──┴──┴──┘    value in its own box

Hàm này sử dụng bất lợi ( ::) để lồng các giá trị trong "ngoặc" (dấu ngoặc được sử dụng ở đây là -1 và -2). Về cơ bản, mỗi khi chúng ta nhân tố và chuyển đổi thành các chỉ số số nguyên tố, _1 được thêm vào trước và _2 được thêm vào, đóng vai trò là dấu ngoặc. Khi hàm được gọi trên các phần tử đó, nó sẽ trả về chúng như nguyên trạng q:sẽ xảy ra lỗi khi cố gắng tính hệ số âm. Nó cũng may mắn mà q:không phải lỗi trên cố gắng để factorize 1 và thay vào đó trả về mảng rỗng (như mong muốn).

Đổi

3 : '2 + }. ; y'
            ;     Raze (remove boxing)
         }.       Behead (remove head)
     2 +          Add 2

Chuyển đổi đơn giản hơn rất nhiều. Nó chỉ loại bỏ tất cả các quyền anh, cũng như yếu tố đầu tiên, sau đó chuyển đổi mọi thứ thành 1 và 0 (chỉ cần thêm 2)

Rơi vãi

(}.~ >:@i.&1)&.|.
             &.|.  Reverse, apply the left function, and then undo
 }.~ >:@i.&1        Drop the leading zeroes and first 1
        i.&1         Index of first one
     >:              Add 1
 }.~                 Drop

Điều này đảo ngược danh sách, tìm cái đầu tiên và sau đó bỏ tất cả các giá trị xuống cái kia, sau đó đảo ngược danh sách một lần nữa.

Giải mã

Giải mã là hàm tích #.hợp có danh sách 1 và 0 và chuyển đổi nó thành số nhị phân.


2

Võng mạc , 244 227 225 byte

+%(G`
\d+
$*0¶$&$*
+`^00(0+)
0$1¶$0
A`^(00+?)\1+$
^0+
$0;1
+`(1+)¶0+(?=¶)
$0;1$1
+`¶(11+?)(\1)*$
¶$1¶1$#2$*1
1$

m`^11$
[]
m`^1+
[¶$.0$*0¶]
+s`(0+);(1+)(.+¶)\1¶
$1;$2$3$2¶
0+;1+¶

)`1+
$.0
T`[]¶`10_
10+$

1
01
+`10
011
^0+

1

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

Đây là một cách tiếp cận thẳng về phía sau thuật toán thể hiện trong câu hỏi. Việc tạo chỉ mục chính là độ phức tạp theo cấp số nhân, vì vậy nó sẽ hết thời gian cho các đầu vào lớn hơn

Giải trình:

+%(G`                Repeatedly apply on each line:
\d+                      If the line is a number, convert it to unary 0s and 1s
$*0¶$&$*
+`^00(0+)                Generate all prefixes of the zeros greater than 1
0$1¶$0
A`^(00+?)\1+$            Remove non-prime strings of zeros
^0+                      Index the first zero set (00) as 1
$0;1
+`(1+)¶0+(?=¶)           Index the rest of the zeroes as their prime index
$0;1$1
+`¶(11+?)(\1)*$          Compute prime factors of input value
¶$1¶1$#2$*1
1$                       Remove the 1 factor (not really prime)

m`^11$                   Turn all 2 prime factors to []
[]
m`^1+                    Surround all non-2 prime factors in brackets
[¶$.0$*0¶]
+s`(0+);(1+)(.+¶)\1¶     Convert non-2 prime factors to their index
$1;$2$3$2¶
0+;1+¶                   Remove the list of primes

)`1+                     Return all primes back to decimal ready to be repeated
$.0
T`[]¶`10_            Then convert all [ to 1 and ] to 0, and remove linefeeds
10+$                 Remove the final 1 and trailing zeroes

1                    Convert from binary to unary
01
+`10
011
^0+

1                    Convert from unary to decimal

1

Haskell , 162 160 155 byte

sum.zipWith((*).(2^))[0..].tail.snd.span(<1).(r%)
r=zip[1..][x|x<-[2..],all((>0).mod x)[2..x-1]]
_%1=[]
((i,q):p)%n|mod n q<1=r%div n q++0:r%i++[1]|1<3=p%n

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

Giải trình:

r=zip[1..][x|x<-[2..],all((>0).mod x)[2..x-1]]định nghĩa một danh sách vô hạn các bộ số nguyên tố và chỉ số của chúng : [(1,2),(2,3),(3,5),(4,7),(5,11),(6,13), ...].

Hàm (%)lấy danh sách này rvà một số nvà chuyển đổi số thành biểu diễn mảng yếu tố đảo ngược. Điều này được thực hiện bằng cách bước qua rcho đến khi chúng ta tìm thấy một số nguyên tố phân chia n. Sau đó chúng tôi đệ quy xác định các đại diện của các chỉ số của thủ này và đặt nó bên trong 01và thêm vào trước các đại diện của nchia cho nguyên tố đó.

Đối với n=46, điều này mang lại danh sách [0,0,0,1,1,0,0,1,1,1,0,1]mà từ đó các số 0 ( snd.span(<1)) và tiếp theo 1( tail) tiếp theo được loại bỏ. Sau đó, danh sách được chuyển đổi thành số thập phân bằng cách nhân phần tử với một danh sách quyền hạn của hai và tổng hợp danh sách kết quả : sum.zipWith((*).(2^))[0..].


0

JavaScript, 289 byte

Các byte là tổng của mã JavaScript không có dấu ngắt dòng sau dấu phẩy (chỉ được chèn để định dạng và dễ đọc hơn) (256 byte) và các ký tự bổ sung cho chuyển đổi dòng lệnh, được yêu cầu khi sử dụng Chrome (33 byte).

'use strict'
var f=(n,i=2,r=[])=>n>1?n%i?f(n,i+1,r):f(n/i,i,r.concat(i)):r,
c=(p,r=1,i=2)=>i<p?f(i)[1]?c(p,r,i+1):c(p,r+1,i+1):r-1?f(r).map(h):[],
h=a=>c(a),
s=a=>a.reduce((r,e)=>r+s(e),'1')+' ',
o=i=>+('0b'+s(f(i).map(h)).trim().replace(/ /g,'0').slice(1,-1))

Và một phiên bản dài hơn, dễ đọc hơn:

'use strict';
const f = (n,i=2,r=[]) => n>1 ? n%i ? f(n,i+1,r) : f(n/i,i,r.concat(i)) : r;
const c = (p,r=1,i=2) => i<p ? f(i)[1] ? c(p,r,i+1) : c(p,r+1,i+1) : r-1 ? f(r).map(h) : [];
const h = i => c(i);
const s = a => a.reduce((r,e) => r+s(e),'1')+' ';
const o = i => +('0b'+s(f(i).map(h)).trim().replace(/ /g,'0').slice(1,-1));

Một số giải thích ngắn gọn:

f là một thuật toán nhân tố đệ quy đuôi hoàn toàn chức năng.

cđếm tại nơi mà rsố nguyên tố pxuất hiện trong chuỗi số nguyên tố và trả về [](nếu p=2r=1) hoặc nhân tố và các quá trình tiếp rtheo bằng phương pháp đệ quy.

hlà một hàm trợ giúp nhỏ không may là cần thiết khi mapgọi hàm được cung cấp với numberOfCurrentElementtư cách là đối số thứ hai và wholeArraylà đối số thứ ba, do đó ghi đè các giá trị mặc định được cung cấp cnếu chúng ta sẽ truyền trực tiếp hàm này (tôi phải mất một thời gian để có được sau cạm bẫy này; thay thế hbằng định nghĩa của nó sẽ dài hơn một vài byte).

sbiến đổi mảng được tạo thành một chuỗi. Chúng tôi sử dụng blankthay vì 0để chúng tôi có thể sử dụng trim()trong o.

olà hàm được gọi với giá trị đầu vào itrả về đầu ra. Nó tạo ra biểu diễn chuỗi nhị phân theo yêu cầu của đặc tả và chuyển đổi nó thành số (thập phân).

Chỉnh sửa: Chrome phải được bắt đầu với chrome --js-flags="--harmony-tailcalls"để cho phép tối ưu hóa đệ quy đuôi (xem https://v8project.blogspot.de/2016/04/es6-es7-and-beyond.html ). Điều này cũng yêu cầu sử dụng chế độ nghiêm ngặt.

Thử nghiệm sau đây cho thấy tính toán hơi chậm đối với một số giá trị (thời gian dài nhất là hơn sáu giây đối 10007với máy tính của tôi). Thật thú vị, nếu không tối ưu hóa đệ quy đuôi, tính toán sẽ nhanh hơn nhiều (về yếu tố 5) khi không có tràn ngăn xếp.

for (let i=3; i<=10008; i==10 ? i=10000 : ++i) {
    let time = new Date().getTime();
    let val = o(i);
    time = new Date().getTime() - time;
    document.write(i + ': ' + o(i) + ' (computed in ' + time + ' ms)<br>');
}

0

tinylisp , 209 byte

(load library
(d [(q((N)(map(q((P)([(length(filter prime?(1to P))))))(reverse(prime-factors N
(d B(q((L)(c 1(insert-end 0(foldl concat(map B L
(d T(q((N)(if(mod N 2)(/ N 2)(T(/ N 2
(q((N)(T(from-base 2(t(B([ N

Dòng cuối cùng là một hàm không tên, tính toán mã hóa được chỉ định. Hãy thử trực tuyến!

Phiên bản trước khi chơi golf

Đây là mã tôi đã có trước khi tôi bắt đầu chơi golf:

(load library)

(def prime-index
 (lambda (P)
  (length (filter prime? (1to P)))))

(def to-list
 (lambda (N)
  (map to-list
   (map prime-index
    (reverse (prime-factors N))))))

(def to-bits
 (lambda (L)
  (cons 1
   (insert-end 0
    (foldl concat
     (map to-bits L))))))

(def trim
 (lambda (N)
  (if (mod N 2)
   (div2 N 2)
   (trim (div2 N 2)))))

(def encode
 (lambda (N)
  (trim
   (from-base 2
    (tail (to-bits (to-list N)))))))

0

05AB1E , 18 byte

ΔÒ.Ø>}¸»Ç3%2K0ܨ2β

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

Giải trình:

Δ    }       # loop until a fixed point
 Ò           # replace each number with its prime factorization
  .Ø>        # replace each prime with its 1-based index
¸»           # after the loop: join to a string
  Ç          # get ASCII value of each character
   3%        # modulo 3 (maps '[' to 1, ']' to 0, ' ' to 2, ',' to 2)
     2K      # remove 2s
       0Ü    # trim trailing 0s
         ¨   # remove the last 1
          2β # parse as base 2
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.