সোনার চেইন কাটুন


32

কোনও ভ্রমণকারীকে শহরের বাইরের একটি হোটেলে n দিনের জন্য থাকতে হবে । তিনি নগদ বাইরে এবং তার ক্রেডিট কার্ড মেয়াদোত্তীর্ণ। তবে তাঁর এন লিঙ্কগুলির সাথে সোনার চেইন রয়েছে ।

এই হোটেলের নিয়মটি হল যে বাসিন্দাদের প্রতিদিন সকালে তাদের ভাড়া দেওয়া উচিত। ট্রাভেলার প্রতিটি দিনের জন্য সোনার চেইনের একটি লিঙ্ক প্রদানের জন্য ম্যানেজারের সাথে চুক্তিতে আসে। তবে ম্যানেজারটি আরও দাবি করেন যে প্রতিদিন যাত্রীদের বেতন দেওয়ার সময় ট্র্যাভেলারটি চেইনে ন্যূনতম সম্ভাব্য ক্ষতি করা উচিত। অন্য কথায়, তাকে যতটা সম্ভব লিঙ্কগুলি কাটানোর সমাধান নিয়ে আসতে হবে।

একটি লিঙ্ক কাটা তিনটি সাবচেইন তৈরি করে: একটিতে কেবল কাটা লিঙ্ক এবং প্রতিটি পাশে একটি one উদাহরণস্বরূপ, 8 দৈর্ঘ্যের একটি চেইনের তৃতীয় লিঙ্কটি কাটা দৈর্ঘ্যের সাবচেইন তৈরি করে [2, 1, 5]। পরিচালকটি পরিবর্তন করতে পেরে খুশি, তাই ট্রাভেলার প্রথম দৈর্ঘ্যের চেইন দিয়ে প্রথম দিন, তারপরে দ্বিতীয় দৈর্ঘ্যের চেইন দিয়ে দ্বিতীয় দিনটি প্রথম চেইনটি ফিরে পেয়ে দিতে পারে।

আপনার কোড দৈর্ঘ্য এন ইনপুট করা উচিত , এবং সর্বনিম্ন দৈর্ঘ্য কাটতে লিঙ্কের একটি তালিকা আউটপুট।

বিধি :

  • n হল পূর্ণসংখ্যা> 0 0
  • লিঙ্কগুলির জন্য আপনি 0-ভিত্তিক বা 1-ভিত্তিক সূচক ব্যবহার করতে পারেন।
  • কিছু সংখ্যার জন্য, সমাধানটি অনন্য নয়। উদাহরণস্বরূপ, যদি n = 15উভয় [3, 8]এবং [4, 8]বৈধ আউটপুট হয়।
  • আপনি হয় তালিকাটি ফেরত দিতে পারেন, বা যেকোন যুক্তিসঙ্গত বিভাজক দ্বারা মুদ্রণ করতে পারেন।
  • এটি , তাই বাইটের মধ্যে সংক্ষিপ্ততম কোডটি জয়ী।

পরীক্ষার কেস :

Input          Output (1-indexed)
1              []
3              [1]
7              [3]
15             [3, 8]
149            [6, 17, 38, 79]

বিস্তারিত উদাহরণ

জন্য এন = 15, লিঙ্ক 3 য় এবং 8 ফলাফল দৈর্ঘ্যের subchains কাটা [2, 1, 4, 1, 7]। এটি একটি বৈধ সমাধান কারণ:

 1 = 1
 2 = 2
 3 = 1+2
 4 = 4
 5 = 1+4
 6 = 2+4
 7 = 7
 8 = 1+7
 9 = 2+7
10 = 1+2+7
11 = 4+7
12 = 1+4+7
13 = 2+4+7
14 = 1+2+4+7
15 = 1+1+2+4+7

শুধুমাত্র একটি কাটা নিয়ে কোনও সমাধান উপস্থিত নেই, সুতরাং এটি একটি অনুকূল সমাধান।

অভিযোজ্য বস্তু

মনে রাখবেন যে এই সমস্যাটি পূর্ণসংখ্যা বিভাজনের সাথে সম্পর্কিত। আমরা একটি পার্টিশন খুঁজছেন পি এর এন 1 থেকে সব পূর্ণসংখ্যার যে এই ধরনের এন অন্তত একটি patition একটি উপসেট থাকা পি

এই সমস্যার জন্য একটি সম্ভাব্য অ্যালগরিদম সম্পর্কে একটি ইউটিউব ভিডিও এখানে ।


আমি আপনার "পরিবর্তন পরিবর্তন" রেফারেন্স বুঝতে পারি না। আপনার পোস্ট করা উদাহরণে, দ্বিতীয় দিন আপনি 2-লিঙ্ক চেইনের সাথে অর্থ প্রদান করেন (এবং 1 টি-লিঙ্ক-চেইন (যা আপনি আগের দিন দিয়েছিলেন) পরিবর্তনের হিসাবে ফিরে পাবেন, আপনার ব্যাখ্যা অনুসারে)) কিন্তু তৃতীয় দিন, আপনি দিয়ে দিতে 1+2। দ্বিতীয় 2 লিঙ্ক-চেইন কোথা থেকে এসেছে?
ফ্ল্যাটার

4
@ ফ্ল্যাটার পরিচালক ইতিমধ্যে এটি আছে। আমরা কেবল অতিরিক্ত অর্থ প্রদান করি। প্রকৃতপক্ষে, আরএইচএস
হ'ল

উত্তর:


15

05AB1E, 23 11 8 bytes

ΔÍN-;иg=

Try it online!

Uses 0-based indexing.

Explanation:

             # start from the implicit input
Δ            # loop forever
 Í           # subtract 2
  N-         # subtract the current iteration number
    ;        # divide by 2
     и       # create a list of length x
      g      # get the length of the list
       =     # print

иg looks like a noop, but it actually does two useful things: it truncates to an integer (; returns a float), and it crashes the interpreter if x is negative (this is the only exit condition).


The 23 byte solution used a very different approach, so here it is for posterity: ÅœʒR2äθP}ʒæOê¥P}θ2äθη€O (TIO, explanation).


2
I've deleted my answer. Mine being 42 and yours being 11 is too big of a difference for me to not feel embarrassed, haha. ;) Nice answer though, and lol at the Ø.Ø. Did you just try some random things in order to both floor and map all negatives to -1? Regardless, very nice answer and much shorter than I anticipated. I was thinking around 20 bytes after i posted my bad 42-byter.
Kevin Cruijssen

2
@KevinCruijssen Nnope, Ø.Ø was actually my first idea. Your comment inspired me to try random things: I found ®Ÿà, ï®M, and more importantly, иg, which yields this nice 8-byter. I always found it annoying that osabie prefers doing nothing over crashing in many cases (div by 0, wrong type, etc), so this crash will come in handy.
Grimmy

2
Hehe, 05AB1E is supposed to never crash, but you're right that it sometimes is a bit annoying it never does.. In the legacy I wouldn't even know how to crash, and in the past we even had an explicit division by zero error we could call manually. xD In the new version it still crashes with an error pretty often when giving incorrect arguments to certain builtins. And nice -3 again.
Kevin Cruijssen

2
"crashes the interpreter if x is negative (this is the only exit condition)." - I love that
John Dvorak

9

Python 2, 75 bytes

f=lambda n,i=0:n>=i<<i and f(n,i+1)or[min(n,2**j*i-i+j)for j in range(1,i)]

Try it online!


Explanation:

Builds a sequence of 'binary' chunks, with a base number matching the number of cuts.

Eg:

63 can be done in 3 cuts, which means a partition in base-4 (as we have 3 single rings):

Cuts: 5, 14, 31, which gives chains of 4 1 8 1 16 1 32 (sorted: 1 1 1 4 8 16 32).

All numbers can be made:

1       1
2       1 1
3       1 1 1
4       4
...
42      1 1 8 32
...
62      1 1 4 8 16 32
63      1 1 1 4 8 16 32

Other examples:

18: 4,11        ->  3 1 6 1 7
27: 5,14,27     ->  4 1 8 1 13 1
36: 5,14,31     ->  4 1 8 1 16 1 5
86: 6,17,38,79  ->  5 1 10 1 20 1 40 1 7

1
Shouldn't you add f= to the start? Since you use a call to f in the lambda function, and I can only assume that you refer to the same lambda you're defining.
randomdude999

@randomdude999, Yeah, I forgot...
TFeld

@randomdude999 does that rule apply to all languages, or just python? Cause I see a javascript answer that is a pure lambda in this challenge...
Shadow

3
@Shadow It applies to all languages, but only for recursive lambdas.
TFeld

1
@Shadow A more generic rule is that you can't reference something that is neither defined in your code nor globally defined in your language, unless it is explicitly allowed by the challenge. The most common case is a recursive function, but this applies to other situations. This answer is another example: f is not recursive, but it's however referenced in the code and therefore has to be named.
Arnauld

8

R, 77 69 bytes

-8 bytes thanks to Aaron Hayman

pmin(n<-scan(),0:(k=sum((a=2:n)*2^a<=n))+cumsum((k+2)*2^(0:k))+1)[-n]

Try it online!

Let k be the number of cuts needed; k is the smallest integer such that (k+1)2kn. Indeed, a possible solution is then to have subchains of lengths 1,1,,1 (k times) and (k+1),2(k+1),4(k+1),8(k+1),,(k+1)2k1. It is easy to check that this is sufficient and optimal.

(The last subchain might need to be made shorter if we exceed the total length of the chain.)

Ungolfed (based on previous, similar version):

n = scan()                            # read input
if(n - 1){                            # If n==1, return NULL
  k = match(F, (a = 2:n) * 2 ^ a > n) # compute k
  b = (k + 1) * 2 ^ (1:k - 1)         # lengths of subchains
  c = 1:k + cumsum(b)                 # positions of cuts
  pmin(c, n )                         # if last value is >n, coerce it to n
}

(Proof that the value of k is as I state: suppose we have k cuts. We then have k unit subchains, so we need the first subchain to be of length k+1. We can now handle all lengths up to 2k+1, so we need the next one to be of length 2k+2, then 4k+4... Thus the maximum we can get out of k cuts is obtained by summing all those lengths, which gives (k+1)2k1.)

If a(k) is the smallest integer n requiring k cuts, then a(k) is OEIS A134401.


I doubt it would help with the special case for n=1, but an alternative way to generate the cutoffs is the recurrence 1, 4, 4a(n-1)-4a(n-2).
Peter Taylor

@PeterTaylor I had a similar recurrence for computing k; this corresponds to OEIS A134401: oeis.org/A134401 But my implementation of the recurrence relation takes up more bytes than the current code.
Robin Ryder

A bit of rearrangement I got it down to 73. Try it online!
Aaron Hayman

@AaronHayman Thanks! Smart move using sum instead of match.
Robin Ryder

69 bytes and got rid of that if statement that was upsetting you: Try it online!
Aaron Hayman



2

C++, 109,107 bytes

-2 bytes thanks to Kevin

#include<iostream>
main(){int n,k=0;for(std::cin>>n;++k<<k<n;);for(n-=k;n>0;k*=2,n-=k+1)std::cout<<n<<',';}

The algorithm is similar to the Robin Ryder's answer. The code is written in a compilable, whole form. Try it!

Details:

std::cin>>n;               // get the value of n as input
while(++k<<k<n);           // determine k
for(n-=k;n>0;k*=2,n-=k+1)  // we don't need n, so the lengths...
    std::cout<<n<<' ';     // of links are subtracted repeatedly

This has a C variation with the same byte length (doesn't seem to need a separate answer):

#include<stdio.h>
main(){int n,k=0;for(scanf("%d",&n);++k<<k<n;);for(n-=k;n>0;k*=2,n-=k+1)printf("%d,",n);}

Two minor things to golf: =0 after k can be removed, since its 0 by default. std::cin>>n;while(++k<<k<n); can be for(std::cin>>n;++k<<k<n;);. I also have the feeling for(n-=k;n>0;k*=2,n-=k+1) can be simplified somehow by combining stuff, but not sure how. PS: Changing the comma-delimiter to a space looks slightly better since you don't see the trailing one imo, but this is purely cosmetic :)
Kevin Cruijssen

1
@KevinCruijssen Thanks, but some compilers don't assign a default value to non-static variables. So I thought =0 was necessary for portability ;) I also realized that the space after #include is not necessary.
polfosol ఠ_ఠ

Ah ok. I don't know C++ too well, so I've used that online compiler you linked in your answer to test some things. :) You forgot the second change I proposed in my comment: the while-loop to a for-loop and putting the std::cin>>n inside it.
Kevin Cruijssen


1

Retina 0.8.2, 61 bytes

.+
11,$&$*
+`\b(1+),(\1(1*)1?\3)$
1$2¶1$1,$3
1+,
1
1A`
1+
$.&

Try it online! 1-indexed port of @Grimy's answer. Explanation:

.+
11,$&$*

Start with N=2 and the input converted to unary.

+`\b(1+),(\1(1*)1?\3)$

Repeatedly try to subtract N from the input and then divide by 2.

1$2¶1$1,$3

If successful, remember 1 more than the input on the previous line, increment N on the current line, and update the input to the new value.

1+,
1

Remove N and increment the last value so that it's also 1-indexed.

1A`

Remove the incremented original input.

1+
$.&

Convert the results to decimal.


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.