Khoảng cách đến bốn


13

Thử thách này dựa trên video này . Tôi khuyên bạn nên xem nó trước khi thử thách này.

Đầu tiên chúng ta định nghĩa một hàm. Hàm này ( OEIS ) lấy số nguyên n làm đầu vào và xuất số lượng chữ cái trong biểu diễn tiếng Anh của n (không có dấu cách hoặc dấu gạch nối). Ví dụ: "ba" có 5 chữ cái nên 3 ánh xạ thành 5.

Như được thể hiện trong video bắt đầu bằng bất kỳ số nào lặp lại quá trình này cuối cùng sẽ dẫn đến bốn, sẽ tự ánh xạ mãi mãi.

Dưới đây là biểu đồ hướng thô cho thấy quỹ đạo của các số nhỏ hơn 16:

  12 11
    \|      
15 2 6 1 10 14 13
  \ \|/ /  /  /
   7 3-/  8--/
    \|   /
 9 0 5--/
  \ \|
   \-4

Thử thách của bạn là xác định số bước mà một số sẽ thực hiện (hoặc số lần chức năng này phải được áp dụng cho một số) trước khi đạt bốn (tức là mức trên biểu đồ được chỉ dẫn trong hình).

Hình thành số tiếng anh

Dưới đây là một lời giải thích ngắn gọn về cách người ta nên hình thành các từ tiếng Anh cho thử thách này:

Các số từ một đến mười chín là:

một, hai, ba, bốn, năm, sáu, bảy, tám, chín, mười, mười một, mười hai, mười ba, mười bốn, mười lăm, mười sáu, mười bảy, mười tám, mười chín

Đối với các số lớn hơn mười chín, quy trình như sau:

Nếu số có hàng trăm vị trí bắt đầu bằng tên của chữ số ở hàng trăm và "trăm".

ví dụ

100 -> "onehundred"

Nếu phần còn lại ít hơn hai mươi thì nối phần đại diện bằng tiếng Anh của phần còn lại.

ví dụ

714 -> "sevenhundredfourteen"

Mặt khác, nếu chữ số hàng chục không bằng 0 nối thêm biểu diễn đúng:

2-> twenty
3-> thirty
4-> forty
5-> fifty
6-> sixty
7-> seventy
8-> eighty
9-> ninety

ví dụ

470 -> "fourhundredseventy"

Cuối cùng, nếu có một chữ số của một người nối thêm đại diện của nó

ví dụ

681 -> "sixhundredeightyone"

Quy định thêm

  • Đối với các số lớn hơn một trăm, bạn nên bỏ "và" khi đếm số lượng chữ cái. Ví dụ 577 là "fivehundredseventyseven" có 23 chữ cái.

  • Chương trình của bạn phải chấp nhận tất cả các số nguyên lớn hơn 0 và dưới 1.000 làm đầu vào thông qua các phương thức tiêu chuẩn.

  • Chương trình của bạn phải xuất số bước cần thiết cho các phương thức đầu ra tiêu chuẩn.

  • Đây là codegolf nên giải pháp có ít byte nhất sẽ thắng.

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

1 -> 3
4 -> 0
7 -> 2
23 -> 5
577 -> 6
600 -> 4 

1
Liên quan Tôi nghĩ rằng đây là một bản dupe, nhưng tôi không thể tìm thấy nó.
DJMcMayhem

Điều gì đã xảy ra với "và"? Hay đúng hơn, tại sao lại bỏ đi và?!
Jonathan Allan

@Jonathan ALLan cuz 'Murica
LegionMammal978

Câu trả lời:


5

JavaScript (ES6), 106 byte

f=(n,a="03354435543668877998")=>n-4&&1+f(7*(n>99)-(-a[n/100|0]-(a[n%=100]||a[n%10])-"0066555766"[n/10|0]))

Các chuỗi dường như là cách tốt nhất để mã hóa độ dài, mặc dù chi phí chuyển đổi số.


Trời ạ, đó gần như chính xác câu trả lời (gần như được đăng) của tôi trông như thế nào, chỉ ngắn hơn 11 byte.
Sản xuất ETH

@ETHproductions Điều tốt là tôi đã giảm 16 byte trước khi đăng nó!
Neil

2

Python, với num2words, 97 113 115 94 93 92 byte

+16 byte (quên dấu gạch nối mà num2words áp dụng, điều này không thực sự thay đổi kết quả của bất kỳ trường hợp kiểm tra nào, mặc dù 23577mỗi trường hợp có dấu gạch nối)
+2 byte (quên bao gồm f=mặc dù đệ quy)
-20 byte (sử dụng re)
-8 byte nhờ @Wheat Wizard (sử dụng ~, thay thế n!=4bằng n-4và ... nhập một dòng> _ <)
-1 byte nhờ @Cyoce (khoảng trắng từ 4 and)

import re,num2words as w
f=lambda n:n-4and-~f(len(re.sub('\W|and','',w.num2words(n))))

Chỉ cần đếm số bước; cũng hoạt động cho các số nguyên lớn và âm ( \Wtìm khoảng trắng, dấu phẩy và dấu gạch nối trong kết quả num2words):

>>> for test in (1,4,7,23,577,600,-1*2**96,3**96):
...     print('test: {0}  ->  {1}'.format(test, f(test)))
...
test: 1  ->  3
test: 4  ->  0
test: 7  ->  2
test: 23  ->  5
test: 577  ->  6
test: 600  ->  4
test: -79228162514264337593543950336  ->  4
test: 6362685441135942358474828762538534230890216321  ->  5

Đây là trường hợp cuối cùng, từng bước một:

sixquattuordecillionthreehundredsixtytwotredecillionsixhundredeightyfiveduodecillionfourhundredfortyoneundecilliononehundredthirtyfivedecillionninehundredfortytwononillionthreehundredfiftyeightoctillionfourhundredseventyfourseptillioneighthundredtwentyeightsextillionsevenhundredsixtytwoquintillionfivehundredthirtyeightquadrillionfivehundredthirtyfourtrilliontwohundredthirtybillioneighthundredninetymilliontwohundredsixteenthousthreehundredtwentyone
fourhundredfiftyone
nineteen
eight
five

1
Bạn không cần f=trước chức năng lambda của mình
Post Rock Garf Hunter

1
Hãy thử import re,num2words as rthay vì hai tuyên bố khác nhau.
Đăng Rock Garf Hunter

1
n-4là điều tương tự nhưn!=4
Post Rock Garf Hunter

1
@WheatWizard num2wordsw, revẫn là re- lưu ý rằng cả hai module và chức năng được gọi lànum2words
Jonathan Allan

1
Ok cái cuối cùng, and 1+có thể được thay thế bằng and-~để lưu một byte
Post Rock Garf Hunter


1

Toán học, 89 byte

Length@FixedPointList[StringLength@StringReplace[IntegerName@#,{" "->"","-"->""}]&,#]-2&

Toán học điển hình: hàm tích hợp tốt, tên hàm dài xấu. FixedPointListáp dụng đối số thứ nhất (một hàm) cho đối số thứ hai liên tục cho đến khi câu trả lời không thay đổi, liệt kê tất cả các kết quả; kết quả bao gồm đầu vào ban đầu và hai bản sao của đầu ra lặp lại, do đó -2ở cuối. Tích hợp sẵn của Mathicala IntegerNamechứa các khoảng trắng và dấu gạch nối, vì vậy chúng ta cần loại bỏ chúng bằng tay.

Khó chịu, IntegerNameđầu ra của 'chứa ký tự "-" (Unicode # 8208) thay vì dấu gạch nối thông thường; đó là lý do tại sao bài nộp này là 89 byte chứ không phải 88. (Và tôi không thể đặt trước mã ở trên với bốn khoảng trắng nó có chấp nhận ký tự Unicode không, bất kỳ trợ giúp nào? Có phải mã trên không hoạt động chính xác nếu bị cắt và dán .)


1

Python 2.7, 344 216 208 byte:

x=`input()`;c=0;y=lambda v:dict(zip(range(0,10),[0]+v));l=[3,3,5,4,4,3,5,5,4];d=y(l);e=y([3,6,6,6,5,5,7,7,6]);f=y([i+7for i in l])
while x!='4':x=`sum([q[int(r)]for q,r in zip([d,e,f],x[::-1])])`;c+=1
print c

Không sử dụng bất kỳ thư viện bên ngoài không giống như câu trả lời Python khác. Đưa đầu vào qua stdinvà đầu ra stdout.

Altern.it với tất cả các trường hợp thử nghiệm!

Giải trình

Đầu tiên tạo ra 3 từ điển với mỗi từ ghép nối độ dài của các từ đại diện từ tiếng Anh của mỗi số với số mà nó đại diện trong khoảng thời gian đóng [1,9]ở các vị trí, hàng chục và hàng trăm tương ứng. Ví dụ, mục đầu tiên trong từ điển dđược 1:3như 1được viết onebằng tiếng Anh và có 3chữ.

Sau đó, mỗi chữ số được đặt trong một số đầu vào chuỗi xđược gán cho từ điển tương ứng của nó, sau đó mỗi số ở mỗi vị trí được khớp với giá trị của nó trong từ điển tương ứng. Ví dụ, giả sử số đầu vào là 23. Vị 20trí hàng chục sẽ được ghép nối với từ điển e, trong đó nó được ghép với 63ở vị trí đó sẽ được ghép nối với từ điển d, trong đó nó được ghép với từ điển 5. Các chữ số trùng khớp này sau đó được thêm vào với nhau để biểu thị độ dài của biểu diễn tiếng Anh của số, được gán thành xmột chuỗi và, miễn là x!='4'vòng lặp while tiếp tục, tăng dần ctheo1mỗi lần để đại diện cho số bước thực hiện cho đến nay. Do đó, 23sẽ tương ứng với 11, lần lượt sẽ tương ứng với 6cái mà sẽ chuyển sang 3và sau đó đến 5và cuối cùng 4, dẫn đến 5tổng số bước.

Cuối cùng, một khi vòng lặp kết thúc, clà đầu ra stdoutđể biểu thị "Khoảng cách đến bốn", trong trường hợp này sẽ là 5.


1

Java, 556 295 byte

Cảm ơn @KevinCruijssen vì đã tiết kiệm 261 byte

  void int(n) {int s[]={0,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,9,8,6,9,9,11,10,6,6,5,5,7,7,6};int c=0,t=(int)Math.pow(10,(int)Math.log10(n)),v=1;while(n>0){if(n/100>0)c+=(s[n/100]+7);else {if(n>0&n<25){c+=s[n];break;}else{c+=s[(n/10)+22];}}n=n%t;t=t/10;}while(c!=4){v++;c=s[c];}System.out.print(v);}


Ung dung:

  void int(n) {

    int s[]={0,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,9,8,6,9,9,11,10,6,6,5,5,7,7,6};
     int c=0,t=(int)Math.pow(10,(int)Math.log10(n)),v=1;
         while(n>0){
            if(n/100>0)
                c+=(s[n/100]+7);
            else {if(n>0&n<25){
                c+=s[n];
            break;
            }
            else{
                c+=s[(n/10)+22];

            }
            }
            n=n%t;
            t=t/10;
        }

        while(c!=4)
        {
            v++;
        c=s[c];
        }
System.out.print(v);
}

Tôi nghĩ rằng bạn có lỗi trong mã của mình, vì s++không thể có trên mảng Chuỗi ..: S
Kevin Cruijssen

@KevinCruijssen Tôi khai báo S (bộ đếm) là INT và STRING quá .... java tự động quyết định đó là INT.
Numberjack

Chà, nếu tôi chạy mã của bạn trong ideone hoặc IDE Eclipse của tôi thì nó không thành công vì bạn có hai s.. Btw, bạn có thể chơi mã của mình với số tiền khá lớn như thế này:int c(int n){int s[]={0,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,8,8,6,9,9,11,10,6,5,5,5,7,6,6},c=0,t=(int)Math.pow(10,(int)Math.log10(n)),x=1;while(n>0)if(n/100>0)c+=s[n/100]+7;else{if(n>0&n<25){c+=s[n];break;}else c+=s[(n/10)+22];}n%=t;t/=10;}for(;c!=4;x++,c=s[c]);return x;}
Kevin Cruijssen

Tôi bị sốc ...... những gì xảy ra với mã của tôi và cảm ơn @ KevinCruijssen..và tôi đang sửa nó ... Cảm ơn một lần nữa.
Numberjack

Np :) Tôi nghĩ rằng nó có thể được đánh gôn thêm bằng cách nào đó mà không sử dụng if-other và đột nhập vào đó (nhưng tôi sẽ để lại cho người khác), nhưng mã ban đầu của bạn là cơ sở tuyệt vời để giải quyết thử thách, vì vậy +1 từ tôi.
Kevin Cruijssen
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.