Đếm hiệu quả


35

Khi tôi còn là một đứa trẻ và muốn đếm các hóa đơn đô la trong khoản tiết kiệm của cuộc đời tôi, tôi sẽ đếm to:

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, hai mươi;
hai mươi mốt, hai mươi hai, hai mươi ba, hai mươi bốn, hai mươi lăm ...

Cuối cùng, tôi cảm thấy mệt mỏi khi phát âm từng số nhiều âm tiết này. Có đầu óc toán học, tôi đã tạo ra một phương pháp đếm hiệu quả hơn nhiều:

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

Như bạn có thể thấy, tôi sẽ chỉ phát âm (các) chữ số đã thay đổi từ số trước đó. Điều này có thêm lợi thế là nó lặp đi lặp lại đáng kể hơn so với tên tiếng Anh cho các số, và do đó đòi hỏi ít năng lực hơn để tính toán.

Thử thách

Viết chương trình / hàm lấy một số nguyên dương và xuất / trả về cách tôi sẽ đếm nó: đó là chữ số khác không nhất và tất cả các số 0 ở cuối.

Ví dụ

   1    1
   2    2
  10   10
  11    1
  29    9
  30   30
  99    9
 100  100
 119    9
 120   20
 200  200
 409    9
1020   20

Một danh sách đầy đủ các trường hợp thử nghiệm không cần thiết. Đây là A274206 trên OEIS.

Quy tắc

  • Mục nhập của bạn về mặt lý thuyết phải hoạt động cho tất cả các số nguyên dương, bỏ qua các vấn đề về độ chính xác và bộ nhớ.
  • Đầu vào và đầu ra phải ở dạng thập phân.
  • Bạn có thể chọn lấy đầu vào và / hoặc đầu ra dưới dạng số, chuỗi hoặc mảng chữ số.
  • Đầu vào được đảm bảo là một số nguyên dương. Mục nhập của bạn có thể làm bất cứ điều gì cho đầu vào không hợp lệ.

Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ thắng.


Vậy "số thập phân" có bao gồm danh sách các chữ số thập phân, như [1,0,2,0]-> [2,0]cho trường hợp kiểm tra cuối cùng không? (Tôi không rõ ràng về cụm từ "mảng đơn mục").
Jonathan Allan

1
@Jonathan ALLan Bởi "mảng đơn mục" Tôi có nghĩa là một mảng có chứa một số hoặc chuỗi đại diện cho số nguyên. Tôi không nghĩ việc cho phép các mảng chữ số là một ý tưởng hay, nhưng bây giờ nó có vẻ như là một hạn chế tùy ý vì các chuỗi được cho phép (và các chuỗi rất giống với các mảng trong nhiều ngôn ngữ). Vì vậy, tôi sẽ cho phép một mảng các chữ số trừ khi có lý do chính đáng để không.
Sản xuất ETH

5
Xin chào, bạn đã đánh cắp bí mật của tôi: P
LegionMammal978

1
Tôi nghĩ rằng hầu hết mọi người đều tính như thế này khi còn bé. ;) Ít nhất tôi cũng làm như vậy. :)
Kevin Cruijssen

7
@KevinCruijssen "khi còn bé"?
Martin Ender

Câu trả lời:


19

Python 2 , 28 byte

f=lambda n:n%10or 10*f(n/10)

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

Một công thức đệ quy làm việc rất sạch sẽ. Nếu chữ số cuối cùng là khác không, hãy xuất nó. Mặt khác, loại bỏ số 0 cuối cùng, tính toán đầu ra cho số đó và nhân nó với 10.


11

Thạch , 6 3 byte

-3 byte bằng cách có I / O dưới dạng danh sách các chữ số thập phân .

ṫTṪ

Bộ thử nghiệm tại Dùng thử trực tuyến!

Làm sao?

ṫTṪ - Main link: listOfDigits  e.g.  [1,    0,    2,    0]  or [1,      1,    9  ]
 T  - truthy indexes                 [1,          3      ]     [1,      2,    3  ]
ṫ   - tail (vectorises)              [[1,0,2,0],  [2,0]  ]     [[1,1,9],[1,9],[9]]
  Ṫ - tail pop                                    [2,0]                       [9]

Nếu chúng ta không thể lấy danh sách thập phân thì 6 byter là:

DµṫTṪḌ

Mà bạn có thể thấy ở đây .

Điều này cũng làm điều tương tự, nhưng chuyển đổi một số nguyên thành một danh sách thập phân trước đó và chuyển đổi lại thành một số nguyên sau đó.


Khi tôi lướt qua vài câu trả lời đầu tiên, tôi tự nhủ: "Tôi cá là có giải pháp Jelly 3 byte ..."
DLosc

9

C, 30 29 27 byte

Tự hào về điều này khi tôi lạm dụng hai khai thác C để đánh gôn này (được mô tả ở cuối bài); Điều này đặc biệt dành cho C (GCC)


3) b=10;f(a){a=a%b?:b*f(a/b);} // 27 byte

2) b;f(a){b=a=a%10?:10*f(a/10);} // 29 byte

1) f(i){return i%10?:10*f(i/10);} // 30 byte

Dùng thử trực tuyến (phiên bản 27 byte)


Lần thử đầu tiên (30 byte): Lạm dụng thực tế là trong GCC nếu không có giá trị nào được khai báo theo thời gian, giá trị có điều kiện sẽ được trả về. Do đó tại sao toán tử ternary của tôi trống cho giá trị trả về sự thật.

Lần thử thứ hai (29 byte): Lạm dụng lỗi bộ nhớ trong GCC, theo như tôi hiểu, nếu một hàm không có giá trị trả về, khi có nhiều hơn hai biến được sử dụng một cách có ý nghĩa trong hàm, giá trị được đặt cuối cùng của biến đối số thứ nhất sẽ được trả lại.
   (Chỉnh sửa: nhưng "giá trị cài đặt" này phải được đặt theo một số cách nhất định, ví dụ: đặt một biến với =hoặc +=hoạt động nhưng đặt nó với%= không hoạt động; lạ)

Nỗ lực thứ ba (27 byte): Vì tôi phải sử dụng một cách có ý nghĩa biến thứ hai (b) để lạm dụng đúng lỗi bộ nhớ được đề cập ở trên, tôi cũng có thể sử dụng nó như một biến thực tế cho "10" để thay thế.
   (Lưu ý: Tôi có thể trao đổi a=a%bvới a%=bđể lưu một byte khác nhưng không may, điều này khiến cho lỗi khai thác bộ nhớ ở trên ngừng "hoạt động", vì vậy tôi không thể)


Bạn có thể muốn thêm "GCC" vào tiêu đề câu trả lời của mình vì nó dành riêng cho GCC (nó không hoạt động trên tiếng kêu). Ngoài ra, "lỗi bộ nhớ" có lẽ chỉ là hành vi không xác định xảy ra để hoạt động do bố cục khung ngăn xếp cụ thể mà GCC sử dụng. Nó có thể không hoạt động trên các nền tảng khác, ngay cả với GCC.
simon

@gurka Xong, cảm ơn
Albert Renshaw

7

Võng mạc , 7 6 byte

!`.0*$

Dùng thử trực tuyến (tất cả các trường hợp thử nghiệm)

Kết quả khớp của một chữ số theo sau bởi bất kỳ số 0 nào ở cuối chuỗi đầu vào. Mặc dù không bắt buộc, điều này cũng xảy ra để làm việc 0.


Huh, tôi đã tìm ra [1-9](hoặc [^0]) sẽ là cần thiết thay vì \d. Tôi đoán sự tham lam của việc *đảm bảo đầu ra chính xác mỗi lần.
Sản xuất ETH

@ETHproductions Điều này không liên quan gì đến sự tham lam *nhưng với thực tế là các trận đấu được tìm kiếm từ trái sang phải. \d0*?$cũng sẽ làm việc
Martin Ender

sử dụng regex .0*$sẽ hoạt động
12Me21

Nếu có một cách (đủ ngắn) để chỉ xuất ra trận đấu cuối cùng, bạn có thể sử dụng.0*
12Me21

@ 12Me21 Cách duy nhất để làm điều đó là chỉ khớp với lần xuất hiện cuối cùng hoặc sử dụng thay thế hoặc một cái gì đó. Nó sẽ không ngắn hơn.
mbomb007

7

Đàn con , 18 32 byte

Tôi nghĩ rằng tôi sẽ phải dành thời gian cho việc này sau và xem liệu tôi có thể nén nó lại một chút không. Nhưng hiện tại nó ở đây.
Hóa ra tôi đã suy nghĩ về điều này hoàn toàn sai lầm. Bây giờ, quá trình tăng dần áp dụng một mod (1,10,100,1000, ...) cho số nguyên đầu vào và in ra cái đầu tiên không bằng không. Bit nhàm chán hơn, nhưng ngắn hơn.

!N%*I1^\.u;u@O\;;r

Hãy thử nó ở đây

    ! N
    % *
I 1 ^ \ . u ; u
@ O \ ; ; r . .
    . .
    . .

Luôn luôn tốt đẹp để xem câu trả lời của Cubix :)
Oliver

@obarakon Có một cải tiến để sớm đưa ra. Thực sự đã làm điều này sai cách
MickyT

5

JavaScript, 21 byte

f=n=>n%10||10*f(n/10)

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


5

Javascript 19 18 byte

Cảm ơn ETHproductions đã chơi golf một byte và Patrick Roberts đã chơi golf hai byte

x=>x.match`.0*$`

Trả về một chuỗi các chuỗi khớp với biểu thức chính ở cuối chuỗi đầu vào với bất kỳ ký tự nào theo sau là số 0 lớn nhất có thể.

Dùng thử trực tuyến


5
Tôi không nghĩ rằng bạn cần g, vì chỉ có một trận đấu để tìm.
Sản xuất ETH

Lưu 2 byte bằng cách sử dụngx=>x.match`.0*$`
Patrick Roberts


3

Vết bẩn , 5 byte

d\0*e

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

Giải trình

       Find the longest substring of the input matching this pattern:
d      a digit, then
 \0*   zero or more 0s, then
    e  edge of input (which is handled as an Nx1 rectangle of characters).

3

Brachylog , 2 byte

a₁

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

Hậu tố dựng sẵn a₁, đối với số nguyên, được triển khai như sau:

brachylog_adfix('integer':1, 'integer':0, 'integer':0).
brachylog_adfix('integer':1, 'integer':I, 'integer':P) :-
    H #\= 0,
    H2 #\= 0,
    abs(P) #=< abs(I),
    integer_value('integer':Sign:[H|T], I),
    integer_value('integer':Sign:[H2|T2], P),
    brachylog_adfix('integer':1, [H|T], [H2|T2]).

Brachylog thích có thể coi các số nguyên là danh sách các chữ số và vì nó sử dụng vị từ tiện ích tùy chỉnh integer_value/2. Điều thú vị integer_value/2ở đây là vì nó phải có thể dịch chính xác một danh sách chữ số với các số 0 đứng đầu, cuối cùng nó cũng có thể dịch một số nguyên sang một danh sách các số có các số 0 đứng đầu, do đó, dự đoán rằng không muốn điều đó xảy ra (hầu hết trong số họ, đặc biệt là những người không thích như a) cấm các đầu của danh sách chữ số của họ bằng 0. Vì vậy, trong khi a₁tạo hậu tố ngắn nhất trước tiên cho danh sách và chuỗi, nó bỏ qua bất kỳ hậu tố nào của số nguyên có 0 đứng đầu, trong đó ngoài việc loại bỏ các bản sao, cũng có nghĩa là hậu tố đầu tiên được tạo là chữ số khác không bên phải với tất cả các số 0 ở cuối.


2

Brain-Flak , 74 byte

{({}<>)<>}(()){{}<>(({}<>)[((((()()()){}){}){}){}]<(())>){((<{}{}>))}{}}{}

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

Chỉ in số 0 khác cuối cùng và tất cả các số 0 ở cuối.

Giải trình:

{({}<>)<>}                    # Move everything to the other stack (reverse the input)
(())                          # Push a 1 to get started
{                             # do...
  {}<>                        #   pop the result of the equals check (or initial 1)
  (                           #   push...
    ({}<>)                    #     the top value from the other stack (also put this on the stack)
    [((((()()()){}){}){}){}]  #     minus the ASCII value of 0
    <(())>                    #     on top of a 1
  )                           #   close the push   
  {                           #   if not zero (ie. if not equal)
    ((<{}{}>))                #     replace the 1 from 3 lines back with a 0
  }{}                         #   end if and pop the extra 0
}                             # while the copied value != "0"
{}                            # pop the result of the equals check


2

TI-Basic, 18 byte

If fPart(.1Ans
Return
Ans.1
prgmA
10Ans

2

R, 33 byte

Được thực hiện như một chức năng chưa được đặt tên

function(x)rle(x%%10^(0:99))$v[2]

Điều này áp dụng một mod từ 10 ^ 0 đến 10 ^ 99. rleđược sử dụng để giảm kết quả xuống để mục thứ hai luôn là kết quả mà chúng ta muốn.
Hãy thử trực tuyến!


2

Zsh , 18 16 byte

<<<${(M)1%[^0]*}

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

Bash , 25 byte

r=${1%[^0]*}
echo ${1#$r}

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


Shell cần phải gọi các chương trình bên ngoài để sử dụng regex, vì vậy chúng ta phải thực hiện với globalbing.

Bản ${1%[^0]*}mở rộng khớp với hậu tố ngắn nhất bắt đầu bằng một ký tự khác 0 và loại bỏ nó.

  • Trong Zsh, việc thêm (M)cờ làm cho hậu tố phù hợp được giữ thay vì xóa.
  • Trong Bash, phần ${1% }mở rộng loại bỏ như một tiền tố bất cứ thứ gì còn lại.

1

GNU sed , 17 14 + 1 (cờ r) = 15 byte

Chỉnh sửa: 2 byte ít hơn nhờ Riley

s:.*([^0]):\1:

Nó hoạt động bằng cách xóa tất cả mọi thứ cho đến chữ số khác không phải, sau đó được in cùng với bất kỳ số 0 nào hiện có. Kịch bản có thể xử lý nhiều thử nghiệm trong một lần chạy, mỗi lần chạy trên một dòng riêng biệt.

Hãy thử trực tuyến! (tất cả các ví dụ kiểm tra)


1

Toán học, 26 byte

Hàm thuần túy lấy danh sách các chữ số và đưa ra danh sách các chữ số:

#/.{___,x_,y:0...}:>{x,y}&

Giải trình

#                           First argument
 /.                           Replace
   {                              start of list followed by
    ___,                          zero or more elements followed by
        x_,                       an element (referred to later as x) followed by
           y:0...                 a sequence of zero or more 0s (referred to later as y) followed by
                 }                end of list
                  :>            with
                    {x,y}         {x,y}
                         &   End of function.

Điều này hoạt động vì nó tìm thấy kết quả khớp ngoài cùng bên trái x, phải là phần tử khác không bên phải của danh sách vì nó được theo sau bởi một chuỗi số 0 nhiều hơn 0và sau đó là cuối danh sách.


1

Java 8, 47 byte

đây là biểu thức lambda có thể gán cho a IntUnaryOperator:

x->{int m=1;for(;x%m<1;m*=10);return x%m*m/10;}

giải thích: nhân m với 10 cho đến khi x%mkhông bằng 0. return x%m*m/10yêu cầu chia vì m là một thứ tự cường độ lớn hơn kết quả mong muốn.



1

TOÁN , 10 7 byte

3 byte được lưu nhờ @B. Mehta!

tfX>Jh)

Đầu vào và đầu ra là một mảng các chữ số.

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

Hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình

t     % Input string implicitly. Duplicate
f     % Push indices of non-zero digits
X>    % Keep maximum, say k
Jh    % Attach 1j to give [k, 1j]. This is interpreted as an index "k:end"
)     % Index into original string. Display implcitly

Vì chúng tôi được phép lấy đầu vào và đầu ra làm một vectơ số nguyên, bạn có thể xóa 48-hoàn toàn, tiết kiệm 3 byte: Hãy thử trực tuyến!
B. Mehta

1

C #, 30 28 byte

Dựa trên câu trả lời JavaScript này , vì vậy tôi cho rằng tất cả các khoản tín dụng dành cho anh ấy.

Chơi gôn

i=a=>a%10<1?10*i(a/10):a%10;
  • -2 byte bằng cách loại bỏ ()xung quanh anhờ Emigna

1
Tôi nghĩ rằng bạn cần đặt tên rõ ràng cho chức năng inày để hoạt động khi bạn đang sử dụng đệ quy.
Emigna

@Emigna bạn nói đúng! Tôi hoàn toàn nhớ điều đó :(
Metoniem

Đã cập nhật nhưng tôi không chắc chắn 100% nếu nó đúng theo cách này
Metoniem

1
Tôi không biết sự đồng thuận về điều này trong C #. Cú pháp đó là hợp lệ, nhưng sẽ chỉ hoạt động nếu đại biểu đã được khai báo (nếu không isẽ không được khai báo cho cuộc gọi đệ quy).
Emigna

1
Dấu ngoặc quanh akhông phải là một trong hai cách.
Emigna

1

J, 27 byte

10&|`(10*(p%&10))@.(0=10&|)

Nó dựa trên công thức của xnor, vì vậy tín dụng cho anh ta.


1

Kotlin, 49 byte

lambda, được giao cho (List<Int>) -> List<Int>

{a->a.slice(a.indexOfLast{it in 1..9}..a.size-1)}
  • tên tham số ngầm định ittrongindexOfLast
  • .. để xây dựng phạm vi

1

Perl 5, 12 byte

11, cộng 1 cho -nEthay vì-e

say/(.0*$)/

1

05AB1E , 9 byte

RD0Ê1k>£R

Hãy thử trực tuyến! hoặc như một bộ thử nghiệm

Giải trình

R          # reverse input
 D         # duplicate
  0Ê       # check each for inequality with 0
    1k     # get the index of the first 1
      >    # increment
       £   # take that many digits from the input
        R  # reverse



@MagicOctopusUrn: Đó chỉ là kiểm tra chữ số cuối cùng. Nó phải là chữ số khác không cuối cùng và tất cả sau đó.
Emigna



1

05AB1E , 4 byte

ĀÅ¡θ

I / O như một danh sách các chữ số.

Dùng thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm (bộ kiểm tra có chứa một liên kết để dễ đọc hơn).

Giải trình:

Ā     # Python-style truthify each digit in the (implicit) input-list (0 if 0; 1 if [1-9])
      #  i.e. [9,0,4,0,3,0,0] → [1,0,1,0,1,0,0]
 Å¡   # Split the (implicit) input-list on truthy values (1s)
      #  i.e. [9,0,4,0,3,0,0] and [1,0,1,0,1,0,0] → [[],[9,0],[4,0],[3,0,0]]
   θ  # And only leave the last inner list
      #  i.e. [[],[9,0],[4,0],[3,0,0]] → [3,0,0]
      # (after which it is output implicitly as result)


0

Haskell 57 byte

f(x:s)a|x=='0'=f s$'0':a|1>0=x:a
t x=f(reverse.show$x)[]

Input    -> Output
t 120    -> "20"
t 30200  -> "200"
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.