16
\$\begingroup\$

The rundown

Create a program that generates an array of random length with random numbers, then apply a series of rules that alter the array. After the rules have been applied, print the sum of the array unless specified otherwise

Array setup

The array must be a random length between 5 and 10 inclusive, with random integers between 1 and 20 inclusive. Each array length should have equal probability of happening and each integer should have an equal probability of being picked per element.

The 7 rules

The rules should act as if they were applied in sequence (eg: rule 1 acts before rule 2) and are only applied once. For proof of rule application, the array must be printed to console after each rule application and once before any rules are applied.

  1. If the array contains a 7, subtract 1 from every element
  2. If rule 1 is applied and the array now contains a 0, add 1 to each element
  3. If the array contains a 13, exclude the 13, and all elements that follow, from the array
  4. If the array contains a 2, exclude all odd numbers
  5. If the array contains a 20, and the third element is even, return 20 as the sum then terminate. If a 20 is present and the third element is odd, return 20 times the length of the array as the sum then terminate.
  6. If the sum is greater than 50, remove the last element repeatedly until it is less than or equal to 50
  7. If the array contains a 16, print the sum in both decimal and hexadecimal.

Example

Here is an initial array,

[20, 2, 5, 7, 14, 8]

Rule 1 can be applied:

[19, 1, 4, 6, 13, 7]

Rule 3 is applied next:

[19, 1, 4, 6]

No other rules are needed, so the program returns 30 as the sum.

Notes

  • I'm not an experienced code golfer, although I can say my personal record is in Python 3 with 369 bytes.
  • The rules don't have to actually be applied in order, but have to act as if they did.
\$\endgroup\$
17
  • 1
    \$\begingroup\$ How random does "random" have to be? \$\endgroup\$
    – hyper-neutrino
    Apr 13 '17 at 4:21
  • 1
    \$\begingroup\$ @HyperNeutrino it can be as sudo-random as you want, but not challenge throwing. Repeats are allowed. \$\endgroup\$
    – Graviton
    Apr 13 '17 at 4:26
  • \$\begingroup\$ How are you going to check if we actually applied the rules? I can just generate a random number under 50 and it would still technically not break any of the rules, and I could just say it "followed" the rules. EDIT: I realise now that this won't work, but people are going to find ways to circumvent the random rules. Are you going to prevent that? \$\endgroup\$
    – clismique
    Apr 13 '17 at 4:29
  • 1
    \$\begingroup\$ At the moment, choosing one of the two arrays [3 3 3 3 4 3] and [4 4 3 4 4], each with probability 50%, is in compliance with what's written under "array setup". So I can just output 19 every time? (Of course, what I really think is that the definition of "random" needs to be clarified.) \$\endgroup\$ Apr 13 '17 at 6:11
  • 3
    \$\begingroup\$ If the array contains a 20, and the third element is even/odd, what if the array has less than 3 elements at this step? \$\endgroup\$
    – Emigna
    Apr 13 '17 at 9:54

18 Answers 18

8
\$\begingroup\$

Python 3, 294 301 287 356 bytes

import random as r
r=r.randint
k=[r(i)+1for i in[20]*r(5,11)]
p=print
if 7in k:k=[i-1for i in k]
p(k)
if 0in k:k=[i+1for i in k]
p(k)
i=k.find(13)
if not~i:k=k[:i]
p(k)
if 2in k:k=[i for i in k if~i%2]
p(k)
a=0
z=len(k)>2and k[2]%2
if 20in k:a=20*len(k)**z
if~z:p(k)
while sum(k)>50:k=k[:-1]
if~z:p(k)
if a:p(a)
else:a=sum(k);p(a,hex(a)*(16in k))
if~z:p(k)

I don't know how you're going to prevent people circumventing the rules, but this one uses the procedure specified.

+7 bytes; thanks to @YamB for saving a few bytes; added a lot more to fix a previous error.
-14 bytes thanks to @RootTwo and myself and also corrected the error.
+83 bytes; this is getting horribly long because OP keeps changing the rules. -some number of bytes thanks to @ZacharyT

\$\endgroup\$
10
  • \$\begingroup\$ All checks out to me, thanks for being honest. \$\endgroup\$
    – Graviton
    Apr 13 '17 at 4:40
  • \$\begingroup\$ You can save 4 bytes by importing 'randint as r' and changing 'if 7in k and 1not in k:k=[i-1...' to 'if 7in k:k=[i+1-int(1in k)...' \$\endgroup\$
    – Graviton
    Apr 13 '17 at 4:44
  • \$\begingroup\$ When initializing k, you don't need the value of i, so you can save 6 bytes with k=[r(1,20)for _ in'-'*r(5,11)]. You can save another byte using k=[i+~-(1in k)*(7in k)for i in k] for rules 1 and 2. \$\endgroup\$
    – RootTwo
    Apr 15 '17 at 6:49
  • 1
    \$\begingroup\$ @Notts90 The rules were changed after I wrote this challenge. I will fix it when I get to a computer. Thanks. \$\endgroup\$
    – hyper-neutrino
    Apr 18 '17 at 10:17
  • \$\begingroup\$ On lines five and seven, you have an unneeded space after the 1, and you can change the print on the second and third to last lines to p. And you ... haven't updated your bytecount. \$\endgroup\$
    – Adalynn
    Jun 14 '17 at 14:49
6
\$\begingroup\$

05AB1E, 91 bytes

5TŸ.RF20©L.R})=D7åi<=D0åi>=}}D13åiD13k£=}D2åiDÈÏ=}D®åiDgs2èÉ®si*},q}[DO50›_#¨=]D16åiDOH,}O,

Try it online! or With input

\$\endgroup\$
2
  • \$\begingroup\$ 84 bytes, and potentially correct? Different? No idea. tio.run/nexus/… \$\endgroup\$ Apr 14 '17 at 18:25
  • \$\begingroup\$ @carusocomputing: I haven't looked through it thoroughly, but it doesn't generate the random array in the beginning nor does it print intermediate results. Will be a bit longer when adding those parts. \$\endgroup\$
    – Emigna
    Apr 16 '17 at 8:14
6
\$\begingroup\$

Javascript (ES6), 344 342 340 342 335 331 333 313 311 305 298 297 290 289 283 279 bytes

Huzzah! Finally tied with beat Arnauld!

Following this exchange* in the challenge's comments and after much deliberation I have decided to use new Date as the seed for the random number generator instead of Math.random(). Doing so means that all the integers in the array will be of the same value.

_=>(l=alert,r=new Date,l(a=[...Array(r%6+5)].map(x=>r%20+1)),i=v=>~a.indexOf(v),i(7)&&l(a=a.map(x=>--x)),i(0)&&l(a=a.map(x=>++x)),i(13)&&l(a=a.slice(0,~i(13))),i(2)&&l(a=a.filter(x=>x%2)),i(t=20)?a[2]%2?t*a.length:t:l(a=a.filter(x=>s+x<51?s+=x:0,s=0))|i(16)?[s,s.toString(16)]:s)

Try it

f=
_=>(l=alert,r=new Date,l(a=[...Array(r%6+5)].map(x=>r%20+1)),i=v=>~a.indexOf(v),i(7)&&l(a=a.map(x=>--x)),i(0)&&l(a=a.map(x=>++x)),i(13)&&l(a=a.slice(0,~i(13))),i(2)&&l(a=a.filter(x=>x%2)),i(t=20)?a[2]%2?t*a.length:t:l(a=a.filter(x=>s+x<51?s+=x:0,s=0))|i(16)?[s,s.toString(16)]:s)
alert(f())

  • Saved 2 bytes by only logging the popped elements in rule 6.
  • Saved 2 bytes by replacing Array(x).fill() with [...Array(x)].
  • Added 2 bytes 'cause I'd messed up on rule 5!
  • Saved 7 bytes fixing the mess I made trying to fix the previous mess!
  • Saved 3 bytes thanks to Arnauld helping me cure a brainfart on rule 2 and saved an additional byte by replacing a +1 with a ~.
  • Added 2 bytes ensuring 0 is returned for an empty array.
  • Saved 20 bytes by finally figuring out how to ditch that fecking while loop.
  • Saved 2 bytes by replacing the , between the last 2 statements with a | and removing the enclosing ().
  • Saved 6 bytes by replacing console.log with alert.
  • Saved 7 bytes by improving the shortcutting of a.includes().
  • Saved 1 byte by editing the implementation of rule 3.
  • Saved 7 bytes by ditching includes() and just using indexOf() throughout.
  • Saved 1 byte by moving the initial declaration of the s variable to somewhere it didn't need a comma.
  • Saved 6 bytes by replacing Math.random() with new Date.
  • Saved 4 bytes by removing the (now redundant) rounding of the random numbers.

Readable & Testable version

  • Added line breaks & comments to code
  • Used console.log instead of alert for your sanity! (Best viewed in your browser's console)
  • Added the current rule number to the output.
  • Commented out random array generation to allow testing by input of a comma separated list of numbers.

f=a=>(
    // Alias alert as l
    // (console.log used for this demo)
    l=(s,a)=>console.log(s+JSON.stringify(a))/*alert*/,
    // Alias new Date as r
    r=new Date,
    // Initiate an array of random length
    // Destructure array
    // Map a random value to each array element
    // (Above all commented out to allow testing your own arrays)
    // Log the initial array
    l("Initial: ",a/*=[...Array(r%6+5)].map(x=>r%20+1)*/),
    // Assign a.indexOf to shortcut i
    i=v=>~a.indexOf(v),
    // Check for the presesnce of 7
    // Invoke the first rule, decrementing the value of each element by 1
    // Log the resulting array
    i(7)&&l("Rule 1: ",a=a.map(x=>--x)),
    // Check for the presesnce of 0
    // Invoke the second rule, incrementing the value of each element by 1
    // Log the resulting array
    i(0)&&l("Rule 2: ",a=a.map(x=>++x)),
    // Check for the presence of 13
    // Invoke the third rule, slicing the array to the index of 13
    // Log the resulting array
    i(13)&&l("Rule 3: ",a=a.slice(0,~i(13))),
    // Check for the presence of 2
    // Invoke the fourth rule, removing all elements whose value have a remainder when divided by 2
    // Log the resulting array
    i(2)&&l("Rule 4:",a=a.filter(x=>x%2)),
    // Assign 20 to variable t
    // (Note: this does not yet save any bytes, but it doesn't cost any either)
    // Check for the presence of 20
    // Invoke the fifth rule, returing 20 times the array length ...
    // ... if the third element (2 in a 0 based index) leaves a remainder when divided by 2 ...
    // ... or just 20, if not
    i(t=20)?"Rule 5: "+(a[2]%2?t*a.length:t):
    // Assign the sum of the array to variable s
    // Invoke the sixth rule by filtering through the array, ...
    // ... adding the value of each element to s, as long as the result is less than 51 ...
    // ... otherwise remove the element from the array
    // Log the current array
    l("Rule 6 :",a=a.filter(x=>s+x<51?s+=x:0,s=0))|
    // Check for the presence of 16
    // If present, invoke the seventh rule, returning the sum and its hex value (as an array)
    // Otherwise simply return the sum
    i(16)?"Rule 7: "+[s,s.toString(16)]:"Sum: "+s
);

document.querySelector`button`.addEventListener(`click`,_=>(console.clear(),console.log(f(document.querySelector`input`.value.split`,`.map(eval)))))
<input><button>Test</button>


*Screenshot, in case it's deleted:

\$\endgroup\$
0
4
\$\begingroup\$

C (gcc), 621 619 593 585 570 562 557 552 529 517 500 482 461 444 442 441 438 bytes

There's a whole lot of golfing needed here... Fixed a bug where it would print the hexidecimal once for each 16 in the list...

Special thanks to ZacharyT with the golf help

#define R r[i]
#define P printf("%d "
#define L for(d=i=0;i<l;i++)
d,i,j,l,r[11];p(i){L P,R);puts("");}main(){srand(time(0));for(l=5+rand()%5;i<l;R=1+rand()%20,i++);for(p();i--;)if(R==7){L--R;j=i=1;}for(p();j&&i<l;i++)if(!R){L++R;j=i=l;}p();L if(R==13)l=i;p();L if(R==2)for(d=1;d;)L if(R&1)for(d=1,--l;i<=l;i++)R=r[i+1];p();L if(R==20)return P,r[3]&1?20*l:20);for(j=i=0;i<l&&j+R<51;j+=R,i++);l=i;p();P,j);L if(R==16)printf("0x%x",j,i=l);}

Try it online!

\$\endgroup\$
11
  • 1
    \$\begingroup\$ Even though you can still golf a lot, you're already 1 byte below my Java answer.. XD Let's see if I can golf it somehow to beat your current submission. ;) \$\endgroup\$ Apr 13 '17 at 14:34
  • \$\begingroup\$ Ok, found something for -3 bytes ;p \$\endgroup\$ Apr 13 '17 at 14:42
  • \$\begingroup\$ If you can golf this down, you might be able to get a "crossed out 444 is still 444" in there! :D \$\endgroup\$
    – hyper-neutrino
    May 13 '17 at 2:44
  • \$\begingroup\$ @HyperNeutrino Golfed off another 2 bytes \$\endgroup\$
    – cleblanc
    May 15 '17 at 12:50
  • \$\begingroup\$ Yay! Nice job :D \$\endgroup\$
    – hyper-neutrino
    May 15 '17 at 12:51
3
\$\begingroup\$

JavaScript (ES6), 296 295 290 289 bytes

A full program that logs the initial array, the intermediate results and the final sum to the console.

f="z=[...Array(5+6j)]Z1+20jw7`-1w0`+1w13_qi+1<-kw2_qn&1^1w20_z[2]&1?a.length*20:20);else{q(s+=n)<51,s=0w16_b.toString(16_;b)}zconsole.log(aw_;if(k=~a.indexOf(v((n,i)=>qz=a.filtervj*Math.random()|0bz.reducevn+i,0)`_z=aZn_))Z.mapv";for(g of "Z_`bjqvwz")e=f.split(g),f=e.join(e.pop());eval(f)

How it works

This was compressed using this JS packer.

Breakdown:

  • Packed string: 226 225 bytes
  • Unpacking code: 69 64 bytes

Below is the original source code with some additional whitespace and line feeds for readability. Rather than applying standard golfing tricks, it was written in a way that produces as many repeating strings as possible in order to please the packer. For instance, the syntax if(k=~a.indexOf(N)) is duplicated everywhere although k is only used in the 3rd rule.

console.log(a=[...Array(5+6*Math.random()|0)].map((n,i)=>1+20*Math.random()|0));
if(k=~a.indexOf(7))
  console.log(a=a.map((n,i)=>n-1));
if(k=~a.indexOf(0))
  console.log(a=a.map((n,i)=>n+1));
if(k=~a.indexOf(13))
  console.log(a=a.filter((n,i)=>i+1<-k));
if(k=~a.indexOf(2))
  console.log(a=a.filter((n,i)=>n&1^1));
if(k=~a.indexOf(20))
  console.log(a[2]&1?20*a.length:20);
else {
  console.log(a=a.filter((n,i)=>(s+=n)<51,s=0));
  if(k=~a.indexOf(16))
    console.log(a.reduce((n,i)=>n+i,0).toString(16));
  console.log(a.reduce((n,i)=>n+i,0))
}

Unpacking methods

The original unpacking code is:

f="packed_string";for(i in g="ABCDEFGHI")e=f.split(g[i]),f=e.join(e.pop());eval(f)

All the following ES6 variants have exactly the same size:

eval([..."ABCDEFGHI"].reduce((f,g)=>(e=f.split(g)).join(e.pop()),"packed_string"))
[..."ABCDEFGHI"].map(g=>f=(e=f.split(g)).join(e.pop()),f="packed_string")&&eval(f)
eval([..."ABCDEFGHI"].map(g=>f=(e=f.split(g)).join(e.pop()),f="packed_string")[8])

The only way I've found so far to shave off a few bytes is to use for ... of:

f="packed_string";for(g of "ABCDEFGHI")e=f.split(g),f=e.join(e.pop());eval(f)
\$\endgroup\$
9
  • \$\begingroup\$ Reading this on a phone so I may be wrong but, in your unpacked code, it looks like rule 2 is being applied regardless of whether or not rule 1 is. \$\endgroup\$
    – Shaggy
    Apr 13 '17 at 20:08
  • 1
    \$\begingroup\$ @Shaggy That's correct. But you can't get a zero unless rule 1 is triggered. \$\endgroup\$
    – Arnauld
    Apr 13 '17 at 21:34
  • \$\begingroup\$ D'oh! Of course! Man, I've been having a ridiculous number of brainfarts during this challenge :( \$\endgroup\$
    – Shaggy
    Apr 13 '17 at 21:48
  • 1
    \$\begingroup\$ @Shaggy Unfortunately not. However, we can save one byte with n&1^1 (it doesn't get packed at all, but is just one byte shorter than !(n&1)). I thought about that at some point and forgot to include it. \$\endgroup\$
    – Arnauld
    Apr 14 '17 at 13:09
  • 1
    \$\begingroup\$ @Shaggy Ahah! Nice job! \$\endgroup\$
    – Arnauld
    May 5 '17 at 17:30
3
\$\begingroup\$

K (ngn/k), 160 147 139 bytes

-13 from consolidating 0N! prints/other tweaks

-8 by converting to ngn/k

{0N!'|(a@:&(~2!a)|^a?2;a:(a?13)#a;a+:|/~a;a-:|/a=7;a:1+(*5+1?6)?20);$[^a?20;;:20*(1;#a)2!a 2];0N!a@:&51>+\a;(+/a),$[^a?16;!0;,`hex@`c$+/a]}

Try it online!

From the beginning to the end...

  • 0N!'| print each of the following in reverse order (when building lists, ngn/k executes the right-most/last list item first, the second-to-last item second, etc. For ease of explanation, the below are listed in the order they are executed)
    • a:1+(*5+1?6)?20 generate 5-10 random numbers between 1 and 20, storing in a
    • a-:|/a=7; decrement a if it contains a 7
    • a+:|/~a; increment a if it contains a 0
    • a:(a?13)#a; take elements occurring before the first 13
    • a@:&(~2!a)|^a?2; if a 2 is present, remove odds from a
  • $[^a?20;;:20*(1;#a)2!a 2]; if 20 is present, check the third value a 2 and early return from the function (otherwise do nothing)
  • 0N!a@:&51>+\a; remove values where the cumulative sum up to that point is >50
  • $[^a?16;+/a;(+/a;`hex@`c$+/a)] return either the sum of a (if no 16 is present), or return the sum as both an integer and in hexadecimal representation (the latter as a string)
\$\endgroup\$
2
\$\begingroup\$

First try at code golf!

Already beat by other javascripters! Dangit! I will improve!!! =)

Javascript -> 550 402 bytes

Could definitely be improved. Compressed Now:

f="ba=[];bl;yz5+5`^=0;i<y;i++)a[i]z20+1|~7j-1|~0j+1|}}~13_l=indexOf(13`ql,y-l-Y_^ in a)if(a[i]%2)qi,Y0)&&(!a[3]%2_k'20'`throw new Error(`}do{l=Vreduce((X,num)=>X+num`ifW)qy-1,1`}whileW|kl`~16))kl.toString(16)`~if(Vincludes(|`ka`z=Zound(Zandom()*yVlengthqVsplice(kalert(j_Vmap((i)=>ibvar `);_)){^for(biZMath.rY1|}~2XtotalW(l>50Va.";for(i in g="VWXYZ^_`bjkqyz|~")e=f.split(g[i]),f=e.join(e.pop());eval(f)

Originial:

var a=[];var l;a.length=Math.round(Math.random()*5+5);for(var i=0;i<a.length;i++)a[i]=Math.round(Math.random()*20+1);alert(a);if(a.includes(7)){a.map((i)=>i-1);alert(a);if(a.includes(0)){a.map((i)=>i+1);alert(a);}}if(a.includes(13)){l=indexOf(13);a.splice(l,a.length-l-1);alert(a);}if(a.includes(2)){for(var i in a)if(a[i]%2)a.splice(i,1);alert(a);}if(a.includes(20)&&(!a[3]%2)){alert('20');throw new Error();}do{l=a.reduce((total,num)=>total+num);if(l>50)a.splice(a.length-1,1);}while(l>50);alert(a);alert(l);if(a.includes(16))alert(l.toString(16));
\$\endgroup\$
2
\$\begingroup\$

Ruby 2.4, 260 bytes

Ruby 2.4 is required for Enumerable#sum.

p a=(1..s=5+rand(5)).map{1+rand(19)}
a.map!{|i|i-1}if a.index 7
p a
a.map!{|i|i+1}if a.index 0
p a
a.pop s-(a.index(13)||s)
p a
a.reject! &:odd?if a.index 2
p a
a.index(20)?p(20*[1,s][(a[2]||1)%2]):((a.pop;p a)while a.sum>50
p m=a.sum;puts"%x"%m if a.index 16)

Try it online! (Neither repl.it nor tio.run support Ruby 2.4 yet, so this online version replaces sum with inject(:+), which has the same behavior.)

\$\endgroup\$
2
\$\begingroup\$

Java 10, 622 619 618 613 576 bytes

v->{var L=new java.util.Stack<Integer>();String r="",N="\n";int c=(int)(Math.random()*6+5),i=c;for(;i-->0;L.add((int)(Math.random()*20+1)));r+=L+N;if(L.contains(7)){for(;++i<c;L.set(i,L.get(i)-1));r+=L+N;}if(L.contains(i=0)){for(;i<c;L.set(i,L.get(i++)+1));r+=L+N;}if((i=L.indexOf(13))>=0){L.subList(i,c).clear();r+=L+N;}if(L.contains(2)){for(i=0;i<L.size();)if(L.get(i)%2>0)L.remove(i);else++i;r+=L+N;}if(L.contains(20))return r+(L.get(2)%2<1?20:20*L.size());i=0;for(var x:L)i+=x;for(;i>50;)i-=L.remove(L.size()-1);return r+L+N+(L.contains(16)?Byte.valueOf(i+"",16)+N:"")+i;}

-1 byte thanks to @Poke
-5 bytes thanks to @ceilingcat.

Try it online.

Explanation:

v->{                          // Method with empty unused parameter and String return
  var L=new java.util.Stack<Integer>();
                              //  Integer-list, starting empty
  String r="",                //  Result-String, starting empty
         N="\n";              //  Temp-String `N`, containing a newline
  int c=(int)(Math.random()*6 //  Get a random integer in the range [0,6]
              +5),            //  And add 5
  i=c;for(;i-->0;             //  Loop that amount of times:
    L.add((int)(Math.random()*20+1)));
                              //   Add a random integer in the range [1,20] to the list
  r+=L+N;                     //  Append the current list + newline to the result-String
  if(L.contains(7)){          //  If the list now contains a 7:
    for(;++i<c;L.set(i,L.get(i)-1));
                              //   Decrease each value by 1
    r+=L+N;}                  //   And append the current list + newline again
  if(L.contains(i=0)){        //  If the list now contains 0:
    for(;i<c;L.set(i,L.get(i++)+1));
                              //   Increase each value by 1
    r+=L+N;}                  //   And append the current list + newline again
  if((i=L.indexOf(13))>=0){   //  If the list now contains a 13:
    L.subList(i,c).clear();   //   Remove all values from that 13 onward from the list
    r+=L+N;}                  //   Append the current list + newline again
  if(L.contains(2)){          //  If the list now contains a 2:
    for(i=0;i<L.size();)      //   Loop over the list:
      if(L.get(i)%2>0)        //    If the current value is odd:
        L.remove(i);          //     Remove it 
      else                    //    Else:
        ++i;                  //     Skip it, and go to the next value
    r+=L+N;}                  //   Append the current list + newline again
  if(L.contains(20))          //  If the list now contains a 20:
    return r                  //   Return the result-String
           +(L.get(2)%2<1?    //   And if the third item is even:
              20              //    Append 20
             :                //   Else (it's odd instead):
              20*L.size());   //    Append the list-size multiplied by 20
  i=0;for(var x:L)i+=x;       //   Set `i` to the sum of the list
  for(;i>50;)                 //  Loop as long as the list-sum is larger than 50:
    i-=L.remove(L.size()-1);  //   Remove the last item of the list
  return r                    //  Return the result-String
         +L+N                 //  Appended with the current list + newline again
         +(L.contains(16)?    //  If the list now contains a 16:
             Byte.valueOf(i+"",16)+N
                              //   Append the sum as hexadecimal
           :                  //  Else:
             "")              //   Append nothing
         +i;}                 //  And append the sum (as regular base-10 integer)

Sample outputs:
Comments behind the sample outputs aren't printed, but I added them as clarification.

[17, 5, 3, 1, 16, 17, 11, 7, 13]   // Initial print (size 9)
[16, 4, 2, 0, 15, 16, 10, 6, 12]   // Rule 1 (contains a 7)
[17, 5, 3, 1, 16, 17, 11, 7, 13]   // Rule 2 (contains a 0)
[17, 5, 3, 1, 16, 17, 11, 7]       // Rule 3 (contains a 13)
[17, 5, 3, 1, 16]                  // Rule 6 (sum must be <= 50)
66                                 // Rule 7 (contains a 16 -> print as Hexadecimal)
42                                 // Print sum as integer

[4, 18, 17, 12, 11, 8]             // Initial print (size 6)
[4, 18, 17]                        // Rule 6 (sum must be <= 50)
39                                 // Print sum as integer

[4, 14, 6, 14, 7, 20, 2, 2]        // Initial print (size 8)
[3, 13, 5, 13, 6, 19, 1, 1]        // Rule 1 (contains a 7)
[3]                                // Rule 3 (contains a 13)
[3]                                // Print is always done after rule 6
3                                  // Print sum as integer
\$\endgroup\$
7
  • 1
    \$\begingroup\$ I'm down to 594 bytes now :-D \$\endgroup\$
    – cleblanc
    Apr 13 '17 at 15:46
  • \$\begingroup\$ @cleblanc I see you're down to 444 now.. I can't compete with that with Java. :) (Funny to say that since 444 is no where near winning compared to all the other answers..) \$\endgroup\$ Apr 14 '17 at 13:29
  • \$\begingroup\$ I know it, even the golfing languages like 05AB1E are almost 100 bytes long. This challenge was a pain. \$\endgroup\$
    – cleblanc
    Apr 14 '17 at 13:34
  • \$\begingroup\$ Can you leave your list generic List a = new ArrayList()? Might save some bytes. You might need to add a typecast when doing actual arithmetic, though. If not, Long is shorter than Integer \$\endgroup\$
    – Poke
    Apr 18 '17 at 20:03
  • \$\begingroup\$ @Poke With a generic List I have to use an (int) cast five times, as well as change the for-each loop from int to Object and add a sixth cast. As for Long: thanks, that saves 1 byte :) (still have to change the for-each from int to long, and r.nextInt(20)+1 to r.nextInt(20)+1L). \$\endgroup\$ Apr 19 '17 at 6:45
1
\$\begingroup\$

R (3.3.1), 325 bytes

Pretty naive implementation; I think I can probably make it a bit shorter.

s=sample(1:20,sample(5:10,1));print(s);if(7%in%s){s=s-1;print(s);if(0%in%s)s=s+1;print(s)};if(13%in%s){s=s[1:(which(s==13)-1)];print(s)};if(2%in%s){s=s[!(s%%2)];print(s)};if(20%in%s){if(s[3]%%2){20*length(s);print(s)}else{20;print(s)}};while(sum(s)>50){s=s[-length(s)];print(s)};if(16%in%s){print(as.hexmode(sum(s)))};sum(s)
\$\endgroup\$
1
\$\begingroup\$

PowerShell, 525 413 bytes

filter a{"$a"};0..(4..9|random)|%{$a+=@(1..20|random)};a;if(7-in$a){$a=($a|%{$_-1});a;if(0-in$a){$a=($a|%{$_+1});a}}$b=$a;$a=@();foreach($z in $b){if($z-ne13){$a+=@($z)}else{a;break}}if(2-in$a){$a=($a|?{$_%2-eq0});a}if(20-in$a){if($a[2]%2){20*$a.count;exit}else{20;exit}}while(($h=$a-join'+'|iex)-gt50){$a=$a[0..($a.count-2)];a}if(16-in$a){$l=0..9+'a b c d e f'-split' ';$q=[math]::floor($h/16);"$q"+$l[$h%16]};$h

Try it online!

I wanted to attempt this one although I figured I wouldn't beat the answers already here :P I have been attempting to golf this down still, I'm sure it's possible with less bytes. Found a better method for hex, but could probably still improve.

Had to cast $a to a string so many times it was better to create a filter for it...

There were quite a few easy golfs I missed such as parentheses and spaces. Might still be some out there?

Somewhat easier to read code:

filter a{"$a"};0..(4..9|random)|%{$a+=@(1..20|random)};a;
if(7-in$a){$a=($a|%{$_-1});a;if(0-in$a){$a=($a|%{$_+1});a}}
$b=$a;$a=@();foreach($z in $b){if($z-ne13){$a+=@($z)}else{a;break}}
if(2-in$a){$a=($a|?{$_%2-eq0});a}
if(20-in$a){if($a[2]%2){20*$a.count;exit}else{20;exit}}
while(($h=$a-join'+'|iex)-gt50){$a=$a[0..($a.count-2)];a}
if(16-in$a){$l=0..9+'a b c d e f'-split' ';$q=[math]::floor($h/16);"$q"+$l[$h%16]};$h
\$\endgroup\$
0
\$\begingroup\$

MATLAB, 275 bytes

I originally planned on maybe a one-liner Octave answer, but requiring output of all applied rules thwarted my plans. Instead, a fairly straightforward MATLAB answer with a few interesting optimisations, e.g. the use of cumsum instead of the obvious while for rule 6. Still, a lot of the byte count is wasted on ifs to prevent output if a rule is not applied.

A=randi(20,1,randi(6)+4)
if any(A==7)
A=A-1
if any(~A)
A=A+1
end;end
q=find(A==13,1);if q
A=A(1:q-1)
end
if any(A==2)
A=A(2:2:end)
end
if any(A==20)
if mod(A(3),2)
20*length(A)
else
20
end;return;end
q=cumsum(A)<51;if any(~q)
A=A(q)
end
q=sum(A)
if(any(A==16))
dec2hex(q)
end

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Scala 587 bytes one liner

import scala.util.Random;object A{def main(args:Array[String])={val s=5+Random.nextInt(6);var a=new Array[Int](s);for(i<-1 to s){a(i-1)=1+Random.nextInt(20)};p(a);if(a.contains(7)&& !a.contains(1)){a.map(a=>a-1);p(a)};if(a.contains(13)){if(a(0)==13)a=new Array[Int](0)else a=a.slice(0,a.indexOf(13));p(a)};if(a.contains(2)){a=a.filter(pred=>pred%2==0);p(a)};if(a.contains(20)){if(a(2)%2==0)println(20)else println(20*a.length)}else{while(a.sum>50)a=a.dropRight(1);val u=a.sum;if(a.contains(16))println(Integer.toHexString(u));println(u)}};def p[T](a: Array[T])=println(a.mkString(","))}

Scala, 763 bytes as is

import scala.util.Random
object TA {
  def main(args:Array[String])={
    val s=5+Random.nextInt(6)
    var a=new Array[Int](s)
    for (i<-1 to s)
      a(i-1)=1+Random.nextInt(20)
    p(a)
    if(a.contains(7) && !a.contains(1)){
      a.map(a=>a-1)
      p(a)
    }
    if(a.contains(13)){
      if (a(0)==13) a=new Array[Int](0) else a=a.slice(0,a.indexOf(13))
      p(a)
    }
   if(a.contains(2)){
      a=a.filter(pred=>pred%2== 0)
      p(a)
    }
    if(a.contains(20)){
      if (a(2)%2==0) println(20) else println(20*a.length)
    }else{
      while(a.sum>50)
        a=a.dropRight(1)
      val u =a.sum
      if (a.contains(16)) println(Integer.toHexString(u))
      println(u)
    }
  }
  def p[T](a: Array[T])={
    println(a.mkString(","))
  }
}
\$\endgroup\$
4
  • \$\begingroup\$ Since this is a code-golf question we do ask that you make at least the easy golfs such as removing unnecessary whitespace. \$\endgroup\$
    – Grain Ghost
    Apr 14 '17 at 2:29
  • \$\begingroup\$ I added the one line low byte version \$\endgroup\$ Apr 17 '17 at 16:54
  • \$\begingroup\$ I don't know Scala, but is the space in a: Array[T] required? You have no space in args:Array[String], which is what resulted in my inquiry. \$\endgroup\$
    – Adalynn
    Jun 13 '17 at 19:26
  • \$\begingroup\$ no I think I missed it. \$\endgroup\$ Jun 13 '17 at 20:55
0
\$\begingroup\$

MATLAB, 228 241bytes

a=randi(20,1,randi(6)+4)
b=@any; 
a=a-b(a==7)
a=a+b(a==0)
a(find(a==13,1):end)=[]
a(and(mod(a,2),b(a==2)))=[]
if b(a==20)
a=[a 0 0 0];
s=20*(1+mod(a(3),1)*(numel(a)-4))
else
a(cumsum(a)>50)=[]
s=sum(a)
if b(a==16)
h=['0x' dec2hex(s)]
end
end

This will apply all rules in order, printing the array value after each step.

The program will crash on rule 5 if the resulting number of elements is less than three. There is currently nothing to say what should happen if there is no third element, so I am assuming that a crash is acceptable. The program will now print 20 if there are less than 3 elements and one or more is a 20.

Interestingly step 2 can be applied regardless of whether step 1 was. This is because the input array will never have a 0 in it meaning that if there are any 0's in the array it must be as a result of step 1 having occurred.

All rules are applied in turn, up until 5, even if there are no changes made. As a result the array will be printed at the start and then after each step up until 5. After step 5 you will either get the sum if it is applied, or no output until after step 6. An extra line containing a could be added after the else statement to ensure that the array value is printed after step 5 at the cost of 2 bytes.


I'd also like to mention that I didn't look at the other answers until after I had written this. I see now that there is another MATLAB answer with some similarities - all of which are coincidental.

\$\endgroup\$
0
\$\begingroup\$

Python 3, 297 293 289, 278 bytes

As Arnauld spotted, you can't get 0 unless rule 1 was applied, which saved on indenting. Thanks to everyone else who commented with suggestions too.

from random import*
p=print
a=b=sample(range(1,20),randint(5,10))
p(a)
if 7in a:a=[i-1for i in a];p(a)
if 0in a:a=b;p(a)
if 13in a:a=a[:a.index(13)];p(a)
if 2in a:a=[i for i in a if~i%2];p(a)
if 20in a and~a[2]%2:a=[20]
while sum(a)>50:a=a[:-1]
b=sum(a)
p(b)
if 16in a:p(hex(b))

Try it online

\$\endgroup\$
2
  • \$\begingroup\$ I don't think you need the space between the and and ~. \$\endgroup\$
    – Adalynn
    Jun 14 '17 at 14:50
  • \$\begingroup\$ i believe from random import* a=b=sample(range(1,20),randint(5,10)) saves some bytes since you can delete line 2. \$\endgroup\$
    – nocturama
    Jun 16 '17 at 19:37
0
\$\begingroup\$

Perl 6, 246 bytes

my&f={.grep($^a)};my&s=->{.say};$_=[(1..20).pick xx(5..10).pick];s;$_»--
if f 7;s;$_»++ if f 0;s;.splice(.first(13):k//+$_);s;$_=[f*%%2]if f 2;
s;say(20*(.[2]%%2||$_)),exit if $_>2&&f 20;s;.pop while
.sum>49;$/=f 16;$_=.sum;s;.base(16).say if $/

Ungolfed:

my &f = { .grep($^a) };  # Helper function: search $_ for something
my &s = -> { .say };     # Helper function: print $_
$_ = [ (1..20).pick xx (5..10).pick ];  # Generate the initial array
s;  # Print the array
$_»-- if f 7;  # Decrement all elements if it contains a 7
s;  # Print the array
$_»++ if f 0;  # Increment all elements if a zero is found
s;  # Print the array
.splice(.first(13):k // +$_);  # Splice out everything from the first 13 onward
s;  # Print the array
$_ = [ f *%%2 ] if f 2;  # Remove all odd elements if a 2 is found
s;  # Print the array
say(20*(.[2] %% 2 || $_)), exit if $_ > 2 && f 20;  # Print and exit, maybe
s;  # Print the array
.pop while .sum > 49;  # Remove elements from the end until sum is below 50
$/ = f 16;  # Save in $/ whether $_ contains a 16
$_ = .sum;  # Set $_ to its own sum
s;  # Print the sum
.base(16).say if $/  # Print the sum in hexadecimal if the last array contained a 16
\$\endgroup\$
0
\$\begingroup\$

Common Lisp, 490 bytes

Here the array is represented as a Common Lisp list.

(let((a(loop for i from 1 to(+ 5(random 5))collect(1+(random 19)))))(flet((p()(format t"~a~%"a))(m(x)(member x a))(h(x)(map-into a x a)))(p)(and(m 7)(h'1-))(p)(and(m 0)(h'1+))(p)(let((p(position 13 a)))(and p(setf a(butlast a (-(length a)p)))))(p)(and(m 2)(setf a(remove-if'oddp a)))(p)(or(and(m 20)(or(and(third a)(oddp(third a))(* 20(length a)))20))(p)(and(setf a(loop for x in a sum x into s while (<= s 50) collect x)) nil)(p)(let((s(reduce'+ a)))(print s)(and(m 16)(format t"~x"s))))))

As usual, large use of and and or as control structures.

(let ((a (loop for i from 1 to (+ 5 (random 5))  ; create initial list
            collect (1+ (random 19)))))
  (flet ((p () (format t "~a~%" a))     ; auxiliary functions: print list
         (m (x) (member x a))           ; check membership
         (h (x) (map-into a x a)))      ; operate on elements
    (p)
    (and (m 7) (h '1-))                 ; if 7 is present decrement all values
    (p)
    (and (m 0) (h '1+))                 ; if 0 is now present increment all values
    (p)
    (let ((p (position 13 a)))          ; remove from 13 (if exists)
      (and p (setf a (butlast a (- (length a) p)))))
    (p)
    (and (m 2) (setf a (remove-if 'oddp a)))   ; if 2 is present remove odd values
    (p)
    (or (and (m 20)                            ; if 20 is present
             (or (and (third a)                ;    when third is present
                      (oddp (third a))         ;         and it is odd
                      (* 20 (length a)))       ;         return 20 times the length
                 20))                          ;    otherwise return 20
        (p)                                    ; otherwise (20 is not present)
        (and (setf a (loop for x in a sum x into s ; compute sum of elements
                        while (<= s 50)            ; limited to 50
                        collect x))                ; and return those elements
             nil)                                  ; (to execute the rest of the code)
        (p)
        (let ((s (reduce '+ a)))                   ; compute the final sum
          (print s)                                ; print the result in decimal
          (and (m 16) (format t "~x" s))))))       ; if 16 is present print also in hexadecimal
\$\endgroup\$
0
\$\begingroup\$

Perl 5 -MList::Util=sum, 256 bytes

$,=$";say$_="@{[map{0|1+rand 20}1..5+rand 6]}";/\b7/&&s/\d+/$&-1/ge&&(say)&&/\b0/&&s/\d+/$&+1/ge&say;s/ ?13.*//&&say;@a=/\d+/g;/\b2\b/&&say@a=grep$_%2-1,@a;/20/&&(say$a[2]%2?20*@a:20)&exit;$t=pop@a while($_=sum@a)>50;$t&&say@a;say;"@a"=~/16/&&printf"%x",$_

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.