title: Integer mark into grade

text:
# Question
Title: Integer mark into grade
Given a positive integer (0 and above, no maximum), convert it into a grade following these rules:

```
A = 100+
B = 90 - 99
C = 80 - 89
D = 70 - 79
E = 60 - 69
F = 59 and less.

```

This felt a little boring, so make the grade a `+` if it's 7,8 or 9 and a `-` if it's 0,1 or 2. Ignore this for the F and A cases.

An example:

**Input:**

```
65

```

**Output:**

```
E

```

Test cases:

```
0  -> F
20 -> F
65 -> E
72 -> D-
75 -> D
80 -> C-
99 -> B+
102 -> A
864 -> A

```

No trailing spaces. One newline after output is fine, but keep it consistent. Functions and full programs are both fine.

This is code golf, so shortest code wins. This was inspired by an Ask Ubuntu question, How to write a shell script to assign letter grades to numeric ranges?. The answers are in bash and python, so slightly spoilers.

---

**Leaderboard:**

Here is a Stack Snippet to generate both a regular leaderboard and an overview of winners by language.

To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:

```
# Language Name, N bytes

```

where `N` is the size of your submission. If you improve your score, you *can* keep old scores in the headline, by striking them through. For instance:

```
# Ruby, <s>104</s> <s>101</s> 96 bytes

```

```
var QUESTION_ID=49876;function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),e.has_more?getAnswers():process()}})}function shouldHaveHeading(e){var a=!1,r=e.body_markdown.split("\n");try{a|=/^#/.test(e.body_markdown),a|=["-","="].indexOf(r[1][0])>-1,a&=LANGUAGE_REG.test(e.body_markdown)}catch(n){}return a}function shouldHaveScore(e){var a=!1;try{a|=SIZE_REG.test(e.body_markdown.split("\n")[0])}catch(r){}return a}function getAuthorName(e){return e.owner.display_name}function process(){answers=answers.filter(shouldHaveScore).filter(shouldHaveHeading),answers.sort(function(e,a){var r=+(e.body_markdown.split("\n")[0].match(SIZE_REG)||[1/0])[0],n=+(a.body_markdown.split("\n")[0].match(SIZE_REG)||[1/0])[0];return r-n});var e={},a=1,r=null,n=1;answers.forEach(function(s){var t=s.body_markdown.split("\n")[0],o=jQuery("#answer-template").html(),l=(t.match(NUMBER_REG)[0],(t.match(SIZE_REG)||[0])[0]),c=t.match(LANGUAGE_REG)[1],i=getAuthorName(s);l!=r&&(n=a),r=l,++a,o=o.replace("{{PLACE}}",n+".").replace("{{NAME}}",i).replace("{{LANGUAGE}}",c).replace("{{SIZE}}",l).replace("{{LINK}}",s.share_link),o=jQuery(o),jQuery("#answers").append(o),e[c]=e[c]||{lang:c,user:i,size:l,link:s.share_link}});var s=[];for(var t in e)e.hasOwnProperty(t)&&s.push(e[t]);s.sort(function(e,a){return e.lang>a.lang?1:e.lang<a.lang?-1:0});for(var o=0;o<s.length;++o){var l=jQuery("#language-template").html(),t=s[o];l=l.replace("{{LANGUAGE}}",t.lang).replace("{{NAME}}",t.user).replace("{{SIZE}}",t.size).replace("{{LINK}}",t.link),l=jQuery(l),jQuery("#languages").append(l)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",answers=[],page=1;getAnswers();var SIZE_REG=/\d+(?=[^\d&]*(?:<(?:s>[^&]*<\/s>|[^&]+>)[^\d&]*)*$)/,NUMBER_REG=/\d+/,LANGUAGE_REG=/^#*\s*([^,]+)/;
```

```
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
```

```
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"><div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table></div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table></div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody></table><table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody></table>
```

# Answer
> 21 votes
# Python 2, ~~72~~ ~~70~~ 62 bytes

```
lambda n:"FA"[n>59:1+n/100]or chr(75-n/10)+"+-"[(n+3)%10/3::2]

```

This is an anonymous function that takes an int and returns the grade as a string.

(thanks to @MartinBüttner, @grc and @TheNumberOne for tips)

# Answer
> 11 votes
# CJam, ~~34 33~~ 32 bytes

```
riAmd)4/"- +"=S-\Ae<5e>_~'L+o5%<

```

Okay, I've tried multiple approaches now and am unable to get this below 33, so here goes the explanation:

```
ri                                 e# Read the input and convert to integer
  Amd                              e# Take divmod of the input with 10. This leaves the
                                   e# number/10 and number%10 on stack
     )4/                           e# Increment the mod by 1 and integer divide by 4.
        "- +"=S-                   e# This converts 0,1,2 to 0 and 7,8,9 to 2. Pick - or +
                                   e# respectively and remove space in case of 3,4,5 and 6
                \Ae<5e>            e# To the divisor by 10 scope it to range of [5,10]
                       _~          e# Take a copy and do number * -1 - 1
                         'L+       e# Add it to char L. This gets us the required grade
                            o      e# Output the grade. This removes it from stack
                             5%    e# We now have scoped divisor on stack. Do mod with 5
                               <   e# Both 5 and 10 will return 0, in which case, we don't
                                   e# want the + or -. So we do a substr(0, 0).
                                   e# 5 represents F and 10, A. For others, it will do
                                   e# substr(0,X) where X > 0. Since the string is only
                                   e# 1 char long, it doesn't affect at all.

```

*UPDATE*: 1 byte saved thanks to a pointer by Dennis

Try it online here

# Answer
> 8 votes
# Retina, 43 + 15 = 58 bytes

```
...+
A
.[012]
$&-
.[789]
$&+
^9.
B
^8.
C
^7.
D
6.
E
\d.*
F

```

**Retina** is a regex language created by Martin Büttner, where the odd-numbered files are the regex to match with, and the even-numbered files are what to replace it with. Each line is a separate file, so I've added 15 bytes for each additional file.

## Explanation

It starts by making anything with 3 or more digits an A. It adds a `-` if it is two-digit number ending with 0, 1, or 2, and `+` if it ends with 7, 8, or 9. The numbers are then mapped to their grade (e.g. a number starting with 9 is given a B). Any number left over is automatically an F. Unfortunately, `;`` must be prepended to all but to the last regex to suppress intermediate output. Update: version 0.5.0 has intermediate output off by default, allowing me to save a few bytes.

# Answer
> 8 votes
## C, 99 bytes

I'm new here, I hope I'm following the rules.

```
char b[3];char*f(n){b[1]=0;n<60?*b=70:n>99?*b=65:(*b=75-n/10,b[1]=n%10<3?45:n%10>6?43:0);return b;}

```

This function takes the mark as a parameter and returns the grade as a NULL-terminated string.

## Explanation

Added whitespace:

```
char b[3];

char *f(n) {
    b[1] = 0;
    n<60 ? *b = 70 :
    n>99 ? *b = 65 :
    (
        *b = 75 - n / 10,
        b[1] = n % 10 < 3 ? 45 : n % 10 > 6 ? 43 : 0
    );

    return b;
}

```

Global variables are automatically initialized to zero, so b is filled with NULLs. Since only the first two characters are ever touched, we only have to worry about putting a NULL in b\[1\] if the grade has only one character. This NULL is inserted at the very beginning of the function. The n parameter is implicitly int. If the grade is less than 60, then it's set to 'F', if it's bigger than 99 it's set to 'A'. In the other cases, the base grade is given by `'E' - (n - 60) / 10`, which simplifies to `75 - n / 10`. `n % 10` gets the units digit of the mark. If it's less than 3 then a - is appended, if it's bigger than 6 a + is appended, otherwise b\[1\] is nulled (which it already was).

## Test cases

```
#include <stdio.h>

char b[3];char*f(n){b[1]=0;n<60?*b=70:n>99?*b=65:(*b=75-n/10,b[1]=n%10<3?45:n%10>6?43:0);return b;}

int main() {
    printf("  0 -> %s\n", f(0));
    printf(" 20 -> %s\n", f(20));
    printf(" 65 -> %s\n", f(65));
    printf(" 72 -> %s\n", f(72));
    printf(" 75 -> %s\n", f(75));
    printf(" 80 -> %s\n", f(80));
    printf(" 99 -> %s\n", f(99));
    printf("102 -> %s\n", f(102));
    printf("864 -> %s\n", f(864));

    return 0;
}

Output:
  0 -> F
 20 -> F
 65 -> E
 72 -> D-
 75 -> D
 80 -> C-
 99 -> B+
102 -> A
864 -> A

```

# Answer
> 7 votes
# Pyth, 33 bytes

```
+C-75K@S[/QTT5)1<-@"- +"/heQ4d%K5

```

Try it online: Demonstration or Test Suite

### Explanation:

```
                                     implicit: Q = input
        [/QTT5)                      create the list [Q/10, 10, 5]
       S                             sort
      @        1                     take the element in the middle
     K                               store in K (this results in a number between 5 and 10)
  -75K                               75 - K
 C                                   char with ASCII-value ...
                  @"- +"/heQ4        "- +"[(Q%10 + 1) / 4]
                 -           d       remove spaces
                <             %K5    slice [:K%5]
+                                    add these two chars and print

```

# Answer
> 7 votes
# \>\<\> (Fish), ~~78~~ 71 bytes

```
iii0)?/:0({:'6'(@@+?/'{'01.
;$-o:'4'(?\'7'(?;'+'o
 ;o'A'\   \'-'o;o'F'\

```

Method:

* We read the codepoints of first 3 characters `x,y,z` from the input. If a character is not present the value of its variable's will be `-1` implicitly. (`ord(c)` will mark the codepoint of the character `c`)
* If `z > 0` (3 digit input) print `A` and exit.
* If `x < ord('6') or y < 0` (input \< 60) print `F` and exit.
* Print the character with codepoint `123 - x`.
* If `y < ord('4') print`-\` and exit.
* If `y > ord('6') print`+\` and exit.
* Exit.

# Answer
> 7 votes
# C, 67 65

Surprisingly, this is quite close to the python solution.

```
f(i){printf(i<60?"F":i>99?"A":"%c%s",75-i/10,"-\0+"+(i%10+1)/4);}

```

But in order for this program, to come to such great shortness, sacrifices had to be made:

* If an `F` or an `A` is printed `printf` doesn't even look at the other arguments passed. This is a quite nasty hack.
* If `(i%10+1)/4` evaluates to `1` (no `+` or `-` should be appended to the grade), the `%s` formatter receives a pointer to a `\0` byte, so nothing is printed. Also quite funny, because I didn't know that you could take the address of an indexed string literal. (e.g. `&"string"[i]`) (**edit**: `"string"+i` is even *shorter*! Thanks @nutki)

Here the output of the program for the numbers 57 to 102. I made it a hexdump, so we can be sure no weird `\0` bytes have been printed.

```
% seq 44 115 | xargs -n1 ./grade | xxd
0000000: 4646 4646 4646 4646 4646 4646 4646 4646  FFFFFFFFFFFFFFFF
0000010: 452d 452d 452d 4545 4545 452b 452b 452b  E-E-E-EEEEE+E+E+
0000020: 442d 442d 442d 4444 4444 442b 442b 442b  D-D-D-DDDDD+D+D+
0000030: 432d 432d 432d 4343 4343 432b 432b 432b  C-C-C-CCCCC+C+C+
0000040: 422d 422d 422d 4242 4242 422b 422b 422b  B-B-B-BBBBB+B+B+
0000050: 4141 4141 4141 4141 4141 4141 4141 4141  AAAAAAAAAAAAAAAA

```

The `main` method used:

```
main(c,v)char**v;{f(atoi(v[1]));}

```

# Answer
> 6 votes
# CJam, ~~41~~ ~~39~~ ~~37~~ 34 bytes

This is way too long, but I don't think I'll be golfing it further for now.

```
qiAmd'K@Ae<5e>:X-X5%g@)4/"- +"=*S-

```

Test it here. Or run all test cases here.

Three bytes saved by Optimizer.

## Explanation

*(Slightly outdated)*

```
qi                                    e# Read input and convert to integer.
  'K1$                                e# Push the character K, then copy the input.
      A/                              e# Divide by 10.
        Ae<5e>                        e# Clamp the result to the range 5..10.";
              -                       e# Subtract from K to get the grade.
               _'Am                   e# Duplicate get difference to A.
                   5%g                e# Check that its neither 0 (A) nor 5 (F).
                      @               e# Pull up the other copy of the input.
                       A%)4/          e# ((i % 10) + 1) / 4
                            "- +"=    e# Use that to select -, space, or +.
                                  *   e# Multiply it with the earlier boolean so that
                                      e# it vanishes for A and F.
                                   S- e# Remove the space if there is one.

```

# Answer
> 6 votes
# GNU sed, 73 + 1 = 74 bytes

The + 1 is for the -r parameter.

```
s/^[1-5]?.$/F/
s/.{3,}/A/
s/[7-9]$/+/
s/[3-6]$//
s/[0-2]$/-/
y/9876/BCDE/

```

# Answer
> 5 votes
# Python 2, ~~94~~ ~~88~~ ~~84~~ 69 bytes

```
lambda g:g>99and'A'or[chr(75-g/10)+'-+'[g%10>2:1-(g%10>6)],'F'][g<60]

```

# Answer
> 5 votes
# JavaScript (ES6), 66 bytes

Straight.

```
F=n=>n<60?'F':n>99?'A':'EDCB'[n/10-6|0]+(n%10>6?'+':n%10<3?'-':'')

// TEST (in Firefox)

for(i=0;i<111;i++)document.write(i+'='+F(i)+' ')
```

# Answer
> 4 votes
# R, ~~107~~ ~~105~~ 99 bytes

Not a very good effort I'm afraid, but I will try and golf it more later.

```
cat(LETTERS[11-(r=min(max(scan(),59),100))%/%10],if(r>59&r<100)c('-','','+')[(r%%10+1)/4+1],sep='')

```

**Edit** Dropped a couple of `if`s. Fixed the case and an incorrect result for 100. ~~Now to get rid of the `ifelse`s~~. Got rid of `ifelse`s.

# Answer
> 3 votes
# Perl, 66 62 bytes

This can probably be golfed more. Also a different way might be better.

```
$_=$_>99?A:$_<60?F:s/\d$/$&>6?"+":$&<3?"-":""/re;y/9876/BCDE/

```

+1 for `-p`

Run with:

```
echo 72 | perl -pE'$_=$_>99?A:$_<60?F:s/\d$/$&>6?"+":$&<3?"-":""/re;y/9876/BCDE/'

```

# Answer
> 2 votes
# Javascript (ES6), ~~78~~ 79 bytes

This really isn't the smartest option, but I did what I could.

```
F=n=>'FEDCBA'[n[2]?5:n<60?0:n[0]-5]+(n[2]||n<60?'':'-+\n'[n[1]<3?0:n[1]>6?1:2])

```

Simply pass the grade **as a string**, and it will return it's grade letter.

The string part in **very** important.

You can check a testcase here:

```
console._RELAY_TO_DOC=true;

//non-es6 version:

function F(n){return 'FEDCBA'[n[2]?5:n<60?0:n[0]-5]+(n[2]||n<60?'':'-+\n'[n[1]<3?0:n[1]>6?1:2])}

var testcases=[0,20,65,72,75,77,80,90,99,100,102,180,1000],
    results={};

for(var i in testcases)
{
  results[testcases[i]]=F(testcases[i]+'');
}

console.log(results);
```

```
<script src="http://ismael-miguel.github.io/console-log-to-document/files/console.log.min.js"></script>
```

~~If the aditional space after the letter isn't allowed, I will happily remove it.~~ **It wasn't!** This increased my code by 1 byte, but nothing (too) serious.

# Answer
> 2 votes
# C#, ~~143~~ ~~127~~ ~~112~~ 88 bytes

```
string g(int n){return n>=100?"A":n<=59?"F":(char)(75-n/10)+(n%10>6?"+":n%10<3?"-":"");}

```

I tried to be clever by doing ASCII number mods, but it seems I wasn't alone!

Thanks to Tim for advice on lists instead of ifs.

Thanks to DarcyThomas for pointing out I could use nested ternary operators.

# Answer
> 1 votes
## C, 102 bytes

```
int f(int h){int b,c;printf("%c%c",b?65:!c?70:75-h/10,!(b=h>99)*(c=h>59)*(((h%10<3)*45+(h%10>6)*43)));

```

}

## Usage

```
#include <stdio.h>
int f(int );
int main(){
    int c;
    scanf("%d",&c);
    f(c);
}

```

# Answer
> 1 votes
# Haskell, 78 bytes

The first line feels wasteful, costing 14 bytes, but I couldn't find a shorter version without it.

```
(#)=replicate
a="A":a
f=(!!)$60#"F"++[g:s|g<-"EDCB",s<-3#"-"++4#""++3#"+"]++a

```

## Explanation

The operator `#` is a shorthand for creating n copies of its second argument. List `a` is an infinite list of Strings "A". Function `f` indexes into a list of all grades for n=0,1,... The list comprehension builds the "middle part" of this list (grades E to B); `g` is a single Char that is prepended to the String `s` (which may be empty).

## Usage

```
ghci> map f [0,20,65,72,75,80,99,102,864]
["F","F","E","D-","D","C-","B+","A","A"]

```

# Answer
> 1 votes
# dc, 52

```
[Anq]sa[Fnq]sf[q]sn16o?A~rd9<ad6>f20r-n1+4/d1=n45r-P

```

### Output

```
$ for i in {0,20,65,72,75,80,99,102,864}; do printf "{%s -> %s} " $i $(dc -e '[Anq]sa[Fnq]sf[q]sn16o?A~rd9<ad6>f20r-n1+4/d1=n45r-P' <<< $i); done
{0 -> F} {20 -> F} {65 -> E} {72 -> D-} {75 -> D} {80 -> C-} {99 -> B+} {102 -> A} {864 -> A} $
$

```

# Answer
> 1 votes
# TI-Basic, 79 74 76 Bytes

```
Input N
If N>99
105->N
sub("FFFFFFEDCBA",1+int(N.1),1
If Ans!="F
Ans+sub("---    +++",1+fPart(N.1),1
Ans

```

# Answer
> 1 votes
# TI-BASIC, ~~69~~ ~~68~~ 66 bytes

```
.1Ans
sub("F?E-E+D-D+C-C+B-B+A",1+2max(0,min(9,int(2Ans)-11)),int(e^(Ans<10 and Ans≥6 and iPart(2.2-5fPart(Ans

```

TI-BASIC is not good for string manipulation.

Input on the calculator homescreen, in the form of \[number\]:\[program name\].

Formatted:

```
.1Ans
sub(                      //Syntax for the substring command is sub(string, index, length)

    "F?E-E+D-D+C-C+B-B+A"                  //String that encodes possible grades

    ,1+2max(0,min(9,            ))         //Starts at "F" if input <60, "A" if >=100
                   int(2Ans)-11           //(Input-55)/5, so starts at "E" from 60 to 64,
                                          //second E from 65-69, D from 70 to 74, &c.

    ,int(e^(                                   //length 1 if false, 2 (includes +/-) if true
            Ans<10 and Ans≥6 and               //grade between 60 and 100
                                 iPart(               //1 if abs. val. of below >= 0.2
                                       2.2-5fPart(Ans  //2.2-.5(last digit)

```

This can probably be golfed further.

# Answer
> 0 votes
# C#, 82 bytes

```
Func<int,string>g=s=>s>99?"A":s<60?"F":(char)(75-s/10)+(s%10<3?"-":s%10>6?"+":"");

```

Here's a fiddle with some test-cases.

# Answer
> 0 votes
# JavaScript (ES6), ~~86~~ 83 bytes

What's really eating up characters is the `String.fromCharCode` and the +/- condition... I strongly suspect there's a clever way to shorten at least one of them.

```
f=n=>n>99?'A':n<60?'F':String.fromCharCode(75.9-n/10|0)+(n%10<3?'-':n%10>6?'+':'');

```

# Answer
> 0 votes
# PHP5.5, 73 bytes

Once again, not the shortest one.

But it works!

```
<?=($n=$_GET[n])<59?F:($n>99?A:'BCDE'[$n[0]-6].'+-'[$n[1]<3?1:2*$n[1]<5])

```

I've classified it under PHP5.5 instead of just PHP since this uses syntax that is only valid for PHP5.5 and PHP5.6.

You can read about string and array dereferencing in the manual:
http://php.net/manual/en/migration55.new-features.php

# Answer
> 0 votes
# Perl, 52

```
#!perl -p
$_=$_>99?A:$_<60?F:"$_"^"s";y/JK7890-6/BC+++\-\--/d

```

# Answer
> 0 votes
# Ruby, 58 Bytes

Couldn't believe that there are no Ruby ones here. On reflection it's fairly similar to some that are here already but anyway:

```
->x{x<60?'F':x>99?'A':(75-x/10).chr+'+-'[(x+3)%10/3].to_s}

```

Try it here

# Answer
> 0 votes
# Excel, 100 bytes

```
=IF(A1<60,"F",IF(A1>99,"A",MID("EDCB",INT(A1/10)-5,1)&IF(MOD(A1,10)<3,"-",IF(MOD(A1,10)>6,"+",""))))

```

---
Tags: code-golf
---


title: Return of the Hydra Slayer

text:
# Question
Title: Return of the Hydra Slayer
Its been a while since you killed that hydra, you basked in the glory for years, but now people are calling you washed up, a has been. Well its time you prove them wrong, you've heard the whereabouts of annother hydra. Simply kill it and you will be awarded all the glory you deserve.

You arrive at the armory to receive your swords but they're all out of regular swords all they have left are Sectors. An n-sector will divide the number of heads on a Hydra by n, but can only be used if the number of heads is divisible by n.

Once again you are going to write some code to help you slay the hydra. Your code will take as input the number of head the hydra, begins the fight with, the number of heads the hydra grows each turn, and a list of n-sectors you can use. Your code will output an optimal pattern of moves to slay the hydra as quickly as possible

Each turn of the fight you may select a single sword to use, if after a slice the hydra has only one head you win, if not it grows heads. You may never make no move, and if there are no possible moves available you lose.

If no solution is possible you may output anything other than a solution, e.g. an empty list, nothing, the number zero, etc.

This is so answers will be scored as their byte counts, with less being better.

# Test cases

Here are some super basic test-cases, more test-cases will be added upon request.

```
24 heads, 1  heads per turn, [2,3] -> [3,3,2,3]
25 heads, 2  heads per turn, [2,3] -> No solutions
4  heads, 2  heads per turn, [2]   -> No solutions
4  heads, 3  heads per turn, [2,5] -> [2,5]
10 heads, 17 heads per turn, [2, 3, 7, 19] -> No solutions
10 heads, 6  heads per turn, [1,16] -> [1,16]
6  heads, 2  heads per turn, [2, 3, 5] -> [2, 5]
125 heads, 1  head per turn, [1, 2, 3, 127] -> [1, 1, 127]

```

# Answer
# JavaScript, ~~191~~ 190 bytes

*Saved a byte thanks to Step Hen*

```
(h,t,s)=>eval(`r=[],d=0,q=[],s.map(a=>q.push([],h));while(q.length){p=q.shift(),h=q.shift(),s.map(w=>(a=h/w)==1?d=w:!(a%1)&!r[a+=t]?r[q.push([...p,w],a),a]=1:0);d?(q=[],p).push(d):0}d?p:[]`)

```

```
f=(h,t,s)=>eval(`r=[],d=0,q=[],s.map(a=>q.push([],h));while(q.length){p=q.shift(),h=q.shift(),s.map(w=>(a=h/w)==1?d=w:!(a%1)&!r[a+=t]?r[q.push([...p,w],a),a]=1:0);d?(q=[],p).push(d):0}d?p:[]`)

console.log(`[${f(24, 1, [2,3])}]`);
console.log(`[${f(25, 2, [2,3])}]`);
console.log(`[${f(4, 2, [2])}]`);
console.log(`[${f(4, 3, [2,5])}]`);
console.log(`[${f(10, 17, [2, 3, 7, 19])}]`);
console.log(`[${f(10, 6, [1,16])}]`);
console.log(`[${f(125, 1, [1, 16])}]`);
console.log(`[${f(1024, 3, [1, 2, 137])}]`);
```

---
> 3 votes

# Answer
# Python 2, ~~169~~ ~~195~~ 222 bytes

+26 bytes to properly handle cyclic head regeneration on bad weapon picks. (Thanks to @ThePirateBay for pointing it out)

+27 bytes to fix certain edge cases causing errors.

```
lambda n,p,w:g(n,n,p,w[::-1])[:-1]
def g(n,b,p,w,a=[]):
 if b<2:return[1]
 for x in w:
	if n%x<1and n/x+p!=n and n not in a:
	 try:
		l=[x]+g(n/x+p,n/x,p,w,[n]+a)
	 	if l and l[-1]!=0:return l
	 except:return[0]
 return[0]

```

Try it online!
> 2 votes

# Answer
# VB.NET (.NET 4.5), 439 + 35 (imports) = 474 bytes

*Requires `Imports System.Collections.Generic`*

```
Const N=Nothing
Function Z(h,r,a,Optional c=N,Optional p=N,Optional ByRef s=N)
If c Is N Then
c=New List(Of Long)
p=New List(Of Long)
End If
If s IsNot N And s?.Count<c.Count Then Return N
If p.Contains(h)Then Return N
p.Add(h)
For i=0To a.Count-1
Dim w=a(i)
If h Mod w=0Then
c.Add(w)
If h\w=1And(s Is N Or s?.Count>c.Count)Then
s=New List(Of Long)
s.AddRange(c)
End If
Z(h\w+r,r,a,c,p,s)
c.RemoveAt(c.Count-1)
End If
Next
Z=s
End Function

```

The function `Z` takes two `Int64` (number of heads and head regrow rate), and a `List(Of Int64)` (Sectors), and returns a `List(Of Int64) (the ordered choice of Sectors). Returns`Nothing\` if there is no solution.

Assumes the Sectors are presented in sorted order from largest to smallest.

The `Optional` parameters are for the recursive calls to save state. They track the current order of Sectors in use, the shortest order of Sectors ever, and the number of heads ever encountered. If we encounter the same number of heads again, there has to have been a shorter way to reach it.

The only ordering of Sectors that matters is I need `1` to be last if it exists. Otherwise, the hydra will might grow without bounds because I could at every turn just use the `1` Sector and never try any other.

I declared a constant `N` to represent `Nothing`, shaving off 6 bytes each time I wanted to use `Nothing`.

`And`/`Or` are not short-circuiting, so I use the null conditional operator (`?.`) to avoid object null errors. In real code, I would use `AndAlso`/`OrElse` which do short-circuit.

Try it online!

---

`Z` un-golfed for readability

```
Public Function Z(currentHeads As Long, regrowRate As Integer, weapons As ISet(Of Long), Optional currentWeapons As List(Of Long) = Nothing, Optional previousHeads As List(Of Long) = Nothing, Optional shortestWeapons As List(Of Long) = Nothing) As List(Of Long)

    ' initial call
    If currentWeapons Is Nothing Then
        currentWeapons = New List(Of Long)
        previousHeads = New List(Of Long)
    End If

    ' we've made more moves than our best so far
    If shortestWeapons IsNot Nothing AndAlso shortestWeapons.Count <= currentWeapons.Count Then
        Return Nothing
    End If

    ' exit, we've been here before
    If previousHeads.Contains(currentHeads) Then
        Return Nothing
    End If

    ' keep track of previous state to prevent duplicate paths
    previousHeads.Add(currentHeads)

    For Each w In weapons

        ' save 1 for last
        If w = 1 Then Continue For

        If currentHeads Mod w = 0 Then
            currentWeapons.Add(w)

            If currentHeads \ w = 1 Then
                If shortestWeapons Is Nothing OrElse shortestWeapons.Count > currentWeapons.Count Then
                    shortestWeapons = New List(Of Long)(currentWeapons)
                End If
            End If

            Dim answer = A(currentHeads \ w + regrowRate, regrowRate, weapons, currentWeapons, previousHeads, shortestWeapons)
            If answer IsNot Nothing Then
                If shortestWeapons Is Nothing OrElse shortestWeapons.Count > answer.Count Then
                    shortestWeapons = New List(Of Long)(answer)
                End If
            End If

            currentWeapons.RemoveAt(currentWeapons.Count - 1)
        End If
    Next

    If weapons.Contains(1) Then
        currentWeapons.Add(1)

        Dim answer = A(currentHeads \ 1 + regrowRate, regrowRate, weapons, currentWeapons, previousHeads, shortestWeapons)
        If answer IsNot Nothing Then
            If shortestWeapons Is Nothing OrElse shortestWeapons.Count > answer.Count Then
                shortestWeapons = New List(Of Long)(answer)
            End If
        End If

        currentWeapons.RemoveAt(currentWeapons.Count - 1)
    End If

    Return shortestWeapons
End Function

```
> 1 votes

---
Tags: code-golf, math, number, game
---


title: Let's learn some soil pH chemistry!

text:
# Question
Title: Let's learn some soil pH chemistry!
Andrew is a chemist, interested in the acidity of solutions and in agriculture. After months of research (Google is not his friend), he came up with the following table\* regarding the human-readable level of acidity in terms of the pH (potential of Hydrogen):

```
         Denomination        |         pH range
                             |
    -------------------------+-----------------------------
    Ultra acidic             |          below 3.5
    -------------------------+------------------------------
    Extremely acidic         |    between 3.5 and 4.4
    -------------------------+------------------------------
    Very strongly acidic     |    between 4.5 and 5.0
    -------------------------+------------------------------
    Strongly acidic          |    between 5.1 and 5.5
    -------------------------+------------------------------
    Moderately acidic        |    between 5.6 and 6.0
    -------------------------+------------------------------
    Slightly acidic          |    between 6.1 and 6.5
    -------------------------+------------------------------
    Neutral                  |    between 6.6 and 7.3
    -------------------------+------------------------------
    Slightly alkaline        |    between 7.4 and 7.8
    -------------------------+------------------------------
    Moderately alkaline      |    between 7.9 and 8.4
    -------------------------+------------------------------
    Strongly alkaline        |    between 8.5 and 9.0
    -------------------------+------------------------------
    Very strongly alkaline   |          over 9.0

```

Given a non-negative decimal number representing the pH of a substance, output its Denomination. You can take input and provide output by any standard method. The data types you are allowed to take input with are:

* Float
* Double
* Your language's standard decimal number data type
* String

And you must output a String representing the denomination. Built-ins related to chemistry are forbidden *(Sorry, Mathematica!)*.

***Approximation Rule:*** If the pH you receive is between an upper bound of a denomination and the lower bound of the next one (e.g. between 7.8 and 7.9), it gets approximated to the closest value between the two: if the pH ≥ upperBound of the first + 0.5, then it should receive the second denomination, but if the pH \< upperBound of the first + 0.5, then it should receive the first one (e.g 7.85 is approximated to 7.9, but 7.84999 is approximated to 7.8). See the test cases for clarifications.

# Test Cases:

```
Input ->  Output

6.40  ->  Slightly acidic
8.399 ->  Moderately alkaline
3.876 ->  Extremely acidic
10.60 ->  Very strongly alkaline
0.012 ->  Ultra acidic
7.30  ->  Neutral
7.85  ->  Moderately alkaline (the approximation rule is applied)
7.849 ->  Slightly alkaline (the approximation rule is applied)
6.55  ->  Neutral (the approximation rule is applied)

```

---

This is , so the shortest valid submission (in bytes) wins!

<sub>**Andrew did not come up with that, it was Wikipedia!*</sub>

# Answer
# Jelly,  ~~77 73~~  71 bytes

```
“£RĿÐƭðṚ°ƲṂṾẒ=ʂXḣsịɠ<»Ḳµ,Ṛ;€"“¡D⁺“a&»j“¿<z»W¤ṙ3
×20<“FYeoy³ƓɗʋṆ‘Sị¢⁾. y

```

A monadic link taking the number and returning a list of characters; or a full program printing the result.

**Try it online!**

### How?

```
“ ... »Ḳµ,Ṛ;€"“¡D⁺“a&»j“¿<z»W¤ṙ3 - Link 1, name list: no arguments
“ ... »                          - compression of "Ultra Extremely Very.strongly Strongly Moderately Slightly"
       Ḳ                         - split at spaces
        µ                        - monadic chain separation, call that adjectives
          Ṛ                      - reverse adjectives
         ,                       - pair these two lists
              “¡D⁺“a&»           - compression of [" alkaline"," acidic"]
             "                   - zip with:
           ;€                    -   concatenate for €ach
                             ¤   - nilad followed by links as a nilad
                       “¿<z»     -   compression of "Neutral"
                            W    -   wrap in a list
                      j          - join
                              ṙ3 - rotate left by 3: ["Strongly alkaline","Moderately alkaline","Slightly alkaline","Neutral","Slightly acidic","Moderately acidic","Strongly acidic","Very.strongly acidic","Extremely acidic","Ultra acidic","Ultra alkaline","Extremely alkaline","Very.strongly alkaline"]

×20<“FYeoy³ƓɗʋṆ‘Sị¢⁾. y - Main link: number, pH
×20                     - multiply by 20
    “FYeqy³ƓɗʋṆ‘        - code-page indexes = [70,89,101,111,121,131,147,157,169,180]
   <                    - less than? (vectorises)
                        -   i.e.: pH < [3.5,4.45,5.05,5.55,6.05,6.55,7.35,7.85,8.45,9]
                S       - sum
                  ¢     - call last link (1) as a nilad
                 ị      - index into (1-indexed and modular)
                        - ...note that the sum is never 11 or 12, so "Ultra alkaline" and
                        -    "Extremely alkaline" wont be fetched, but that a sum of 0
                        -    fetches "Very.strongly alkaline", as required.
                   ⁾.   - literal list of characters ['.', ' ']
                      y - translate (replace any '.' with a ' ' i.e. for "Very.strongly")
                        - if running as a full program, implicit print

```
> 6 votes

# Answer
# PHP, 199 bytes

```
foreach([35,9.5,6,5,5,5,8,5,6,5.5]as$l)$p+=$argn*10>=$s+=$l;$p-=$argn==9;echo[Ultra,Extremely,"Very strongly",Strongly,Moderately,Slightly][$p>6?12-$p:$p],[" acidic",Neutral," alkaline"][1+($p<=>6)];

```

Try it online!
> 5 votes

# Answer
# C# (.NET Core), 236 bytes

```
p=>{var l=new[]{70,89,101,111,121,131,147,157,169,180,280};var a="Ultra,Extremely,Very strongly,Strongly,Moderately,Slighty, acidic,Neutral, alkaline".Split(',');int i=0;for(;p*20>=l[i];i++);return i==6?a[7]:i<6?a[i]+a[6]:a[12-i]+a[8];}

```

Try it online!

This solution considers that `p` cannot be greater than 14.
> 4 votes

# Answer
# T-SQL, ~~305~~ 299 bytes

```
DECLARE @ char(999)=REPLACE(REPLACE(REPLACE(REPLACE('SELECT TOP 1i FROM(VALUES(''Very s$#9&S$#8.4&Moderately#7.8&Slightly#7.3&Neutral'',6.5&Slightly@6&Moderately@5.5&S$@5&Very s$@4.4&Extremely@3.4&Ultra@-1))x(i,j),t WHERE j<a','#',' alkaline'','),'@',' acidic'','),'&','),('''),'$','trongly')EXEC(@)

```

Input is via a pre-existing table *t* with `DECIMAL(4,1)` column *a*, per our Input/Output rules.

Because of the `DECIMAL(4,1)` data type, any "approximation rule" rounding takes place when the value is entered into the input table, so doesn't need to be explicitly managed by my code.

After the space-saving `REPLACES` are performed, this is a simple SQL query joining our input table with our list of values:

```
SELECT TOP 1 i
FROM(VALUES
    ('Very strongly alkaline',9),
    ('Strongly alkaline',8.4),
    ('Moderately alkaline',7.8),
    ('Slightly alkaline',7.3),
    ('Neutral',6.5),
    ('Slightly acidic',6),
    ('Moderately acidic',5.5),
    ('Strongly acidic',5),
    ('Very strongly acidic',4.4),
    ('Extremely acidic',3.4),
    ('Ultra acidic',-1)
) x(i,j), t
WHERE j<a

```

I reverse the order so `TOP 1` picks the first one less than our input value.

Even this form (after removing line breaks and extra spaces) is pretty good, at **318 bytes**. Adding the overhead of the `DECLARE`, `REPLACES` AND `EXEC` only becomes worth it with all the repeated phrases.

**EDIT**: Save 6 bytes by removing unnecessary ".0" on several values
> 4 votes

# Answer
# 05AB1E, ~~81~~ ~~80~~ ~~79~~ ~~77~~ ~~76~~ 74 bytes

```
'Äˆ“¢³¿™ly³¾‚Òw““³¾§ÓªÅ“«#Â¦¦’šÉaƒ£’«Š’w¡Îic’«)˜™'wð:I•t{~À•ST+.¥70+20/‹Oè

```

Try it online!

Test suite

**Explanation**

```
'Äˆ                   # push the string "neutral"
“¢³¿™ly³¾‚Òw“         # push the string "slightly moderately strongly veryw"
“³¾§ÓªÅ“              # push the string "strongly extremely ultra"
«                     # concatenate the top 2 items on the stack
 #                    # split on spaces
  Â                   # push a reversed copy
   ¦¦                 # remove the first 2 elements of the copy ("ultra", "extremely")
’šÉaƒ£’«              # append the string "walkaline" to each ("walk"+"a"+"line")
        Š             # move down 2 places on the stack
’w¡Îic’«              # append the string "wacidic" to each ("w"+"acid"+"ic")
        )˜            # wrap stack in a list and flatten
          ™           # title case each
           'wð:       # replace each instance of "w" with a space
I                     # push input
 •t{~À•               # push the base 255 compressed number 920006021
       ST+            # split to list of digits and add 10 to each
          .¥          # undelta (compute increments from 0)
            70+       # add 70 to each
               20/    # divide each by 20
                  ‹   # compute input less than for each
                   O  # sum
                    è # use this to index into list of strings

```
> 3 votes

# Answer
# Retina, 228 bytes

```
$
.00
\.(.)\.?(.).*
$1$2
.+
$*
1{900,}
VA
1{845,}
STA
1{785,}
MA
1{735,}
SLA
1{655,}
Neutral
1$
1 acidic
1{605,}
SL
1{555,}
M
1{505,}
ST
1{445,}
V
1{350,}
Extremely
1+
Ultra
M
Moderately
V
Very sT
T
trongly
L
lightly
A
 alkaline

```

Try it online! Link includes test suite. Explanation:

```
$
.00
\.(.)\.?(.).*
$1$2

```

Multiply the input by 100 by suffixing a spare decimal point and two zeros then deleting the decimal point and all but two digits after it.

```
.+
$*

```

Convert to unary.

```
1{900,}
VA
1{845,}
STA
1{785,}
MA
1{735,}
SLA

```

Handle all the alkalis, converting into abbreviations that will be expanded later.

```
1{655,}
Neutral

```

Handle neutral.

```
1$
1 acidic

```

Anything left must be acidic. (But leave the 1 in case the pH is 0.001)

```
1{605,}
SL
1{555,}
M
1{505,}
ST
1{445,}
V
1{350,}
Extremely
1+
Ultra

```

Handle all the acids.

```
M
Moderately
V
Very sT
T
trongly
L
lightly
A
 alkaline

```

Expand the abbreviations.
> 2 votes

# Answer
# Python 2, 202 bytes

*-15 bytes thanks to @JonathanAllan*

```
lambda k:'Neutral_Slightly_Moderately_Strongly_Very strongly_Extremely_Ultra'.split('_')[abs(sum(round(k*10)>ord(i)for i in'",27<AINT')+(k>9)-(3.45<k<3.5)-6)]+(' acidic'*(k<6.55)or' alkaline'*(k>=7.35))

```

Try it online!
> 2 votes

# Answer
## JavaScript (ES6), ~~192~~ ~~189~~ ~~185~~ 184 bytes

```
k=>([...'09544474540'].some(n=>(i--,k-=++n)<0,i=7,k=k*10-33.5),'Neutral,Slightly,Moderately,Strongly,Very strongly,Extremely,Ultra'.split`,`[i<0?-i:i]+(i?i>0?' acidic':' alkaline':''))

```

### Test cases

```
let f =

k=>([...'09544474540'].some(n=>(i--,k-=++n)<0,i=7,k=k*10-33.5),'Neutral,Slightly,Moderately,Strongly,Very strongly,Extremely,Ultra'.split`,`[i<0?-i:i]+(i?i>0?' acidic':' alkaline':''))

console.log(f(6.40))  //  Slightly acidic
console.log(f(8.399)) //  Moderately alkaline
console.log(f(3.876)) //  Extremely acidic
console.log(f(10.60)) //  Very strongly alkaline
console.log(f(0.012)) //  Ultra acidic
console.log(f(7.30))  //  Neutral
console.log(f(7.85))  //  Moderately alkaline
console.log(f(7.849)) //  Slightly alkaline
console.log(f(6.55))  //  Neutral
```
> 2 votes

# Answer
# Excel, 240 bytes

```
=CHOOSE((A1<6.55)+(A1<6.05)+(A1<5.55)+(A1<5.05)+(A1<4.45)+(A1<3.5)+(A1>=7.35)+(A1>=7.85)+(A1>=8.45)+(A1>9)+1,"Neutral","Slightly","Moderately","Strongly","Very Strongly","Extremely","Ultra")&IF(A1<6.55," acidic",IF(A1>=7.35," alkaline",""))

```
> 1 votes

# Answer
## Javascript, ~~222~~ 209 bytes

```
x=>'Very strongly,Strongly,Moderately,Slightly,Neutral,Extremely,Ultra'.split(',',7,x-=0.049)[x>9?0:x>8.4?1:x>7.8?2:x>7.3?3:x>6.5?4:x>6?3:x>5.5?2:x>5?1:x>4.4?0:x>3.5?5:6]+(x<6.5?' acidic':x>7.3?' alkaline':'')

```

Still golfing it a little

```
var f = x=>'Very strongly,Strongly,Moderately,Slightly,Neutral,Extremely,Ultra'.split(',',7,x-=0.049)[x>9?0:x>8.4?1:x>7.8?2:x>7.3?3:x>6.5?4:x>6?3:x>5.5?2:x>5?1:x>4.4?0:x>3.5?5:6]+(x<6.5?' acidic':x>7.3?' alkaline':'')

console.log(f(6.40));
console.log(f(8.399));
console.log(f(3.876));
console.log(f(10.60));
console.log(f(0.012));
console.log(f(7.30));
console.log(f(7.85));
console.log(f(7.849));
console.log(f(6.55));
```
> 0 votes

---
Tags: code-golf, string, chemistry
---


# Question
Title: Chemistry 101 - Introduction to the Periodic Table
## Question

`Given the atomic number of an element` in the range \[1-118\] output the `group and period`, of that element as given by the following Periodic Table Of Elements.

For elements in the Lanthanide and Actinide series, (ranges \[57-71\] and \[89-103\]), you should instead return `L` for the Lanthanides and `A` for the Actinides

> You may write a program or a function and use any of the our standard methods of receiving input and providing output.
>
> You may use any programming language, but note that these loopholes are forbidden by default.

\[Source\]

## Test Cases

Since there are only 118 possible inputs, a full list of the expected inputs and outputs is given below.

*Created by hand, let me know if there's a mistake!*

```
1,1,1
2,18,1
3,1,2
4,2,2
5,13,2
6,14,2
7,15,2
8,16,2
9,17,2
10,18,2
11,1,3
12,2,3
13,13,3
14,14,3
15,15,3
16,16,3
17,17,3
18,18,3
19,1,4
20,2,4
21,3,4
22,4,4
23,5,4
24,6,4
25,7,4
26,8,4
27,9,4
28,10,4
29,11,4
30,12,4
31,13,4
32,14,4
33,15,4
34,16,4
35,17,4
36,18,4
37,1,5
38,2,5
39,3,5
40,4,5
41,5,5
42,6,5
43,7,5
44,8,5
45,9,5
46,10,5
47,11,5
48,12,5
49,13,5
50,14,5
51,15,5
52,16,5
53,17,5
54,18,5
55,1,6
56,2,6
57,L,
58,L,
59,L,
60,L,
61,L,
62,L,
63,L,
64,L,
65,L,
66,L,
67,L,
68,L,
69,L,
70,L,
71,L,
72,4,6
73,5,6
74,6,6
75,7,6
76,8,6
77,9,6
78,10,6
79,11,6
80,12,6
81,13,6
82,14,6
83,15,6
84,16,6
85,17,6
86,18,6
87,1,7
88,2,7
89,A,
90,A,
91,A,
92,A,
93,A,
94,A,
95,A,
96,A,
97,A,
98,A,
99,A,
100,A,
101,A,
102,A,
103,A,
104,4,7
105,5,7
106,6,7
107,7,7
108,8,7
109,9,7
110,10,7
111,11,7
112,12,7
113,13,7
114,14,7
115,15,7
116,16,7
117,17,7
118,18,7

```

## Scoring

Simple . Shortest number of bytes wins

# Answer
> 10 votes
## CJam, ~~64~~ ~~59~~ ~~58~~ ~~56~~ 54 bytes

*Thanks to Dennis for saving 2 bytes.*

```
{_80-zG-z8<{80>"LA"=}{_"X8"f>[-14_AAGH].*+:+Imd)}?}

```

Try it online!

Leaves either period and group or a single character on the stack.

### Explanation

There are two main ideas here:

* First, we deal with the Lanthanides and Actinides. We have the condition **56 \< x \< 72** for Lanthanides and **88 \< x \< 104** for Actinides. Both of these can be expressed as a single comparison by taking an absolute difference to the centre of the range: the inequalities become **|x - 64| \< 8** and **|x - 96| \< 8**, respectively. But these are still very similar, and doing the two comparisons separately is expensive. So we apply the same idea of checking a symmetric range, by taking another absolute difference with the centre *between* the two ranges, **80**, first: **||x-80| - 16| \< 8**. This condition indicates that the atom is either a Lanthanide or an Actinide, but distinguishing between these two cases is then as trivial as comparing against 80 (or some other value between the ranges).
* Since the output is really an index in a table of width 18, an obvious approach is to try base-converting the value to base 18, so that the two digits give group and period. To do that, we need to shift some values around though. All the we really need to do is to add the gaps in periods 1, 2 and 3 and close the gaps in periods 6 and 7. It's easiest to do this from the end, so that the values of the other gaps aren't affected (and keep their values).

```
_            e# Make a copy of the input, to figure out whether the output
             e# should be L or A.
80-z         e# Absolute difference from 80.
G-z          e# Absolute difference from 16.
8<           e# Check whether the result is less than 8.
{            e# If so...
  80>        e#   Check whether the input is greater than 80.
  "LA"=      e#   Select 'L or 'A accordingly.
}{           e# ...otherwise...
  _          e#   Duplicate input again.
  "X8"    e#   Push a string with character codes [88 56 12 4 1].
             e#   These are the values just before the gaps.
  f>         e#   Compare the input to each of these.
  [-14_AAGH] e#   Push [-14 -14 10 10 16 17]. These are the changes we need to
             e#   make to remove or insert the gaps corresponding to the above
             e#   positions. Note that the 17 doesn't get paired with an offset.
             e#   It's a constant offset to itself, which is equivalent to
             e#   decrementing the input (to make it zero based) and adding 18
             e#   to make the increment the period and make it 1-based.
  .*         e#   Multiply each gap by whether it's before the input value.
  +:+        e#   Add all of the applicable gaps to the input value.
  Imd        e#   Divmod 18, gives 1-based period and 0-based group.
  )          e#   Increment the group to make it one-based.
}?

```

# Answer
> 9 votes
# 05AB1E, ~~113~~ ~~102~~ 99 bytes

```
X18©XY‚Dˆ13®Ÿ¯13®Ÿ®LD¯15'L×S15L3+©¯15'A×S®)˜¹<è,XXY8×SD>4 18×SD>S66Sð14×S6 15×S77Sð15×S7 15×S)˜¹<è,

```

Explanation:

```
(start to construct the period part)
X18 ~ push 1 and 18
© ~ store 18 in register_c without p-opping
XY ~ push 1 and 2
13® ~ push 13 and the top element in register_c (18)
Ÿ ~ range - pop 2 values and push [a .. b]
XY ~ push 1 and 2
13®Ÿ ~ range - 13 to 18
XY ~ push 1, 2
13®Ÿ ~ range - 13 to 18
®LD ~ range - 1 to 18 (twice)
2L ~ range - 1 to 2
15'L×S ~ push 'L' 15 times
15L ~ range - 1 to 15
3+ ~ add 3 to each value in topmost element in stack
© ~ store in register-c without popping
2L ~ range - 1 to 2
15'A×S ~ push 'A' 15 times
® ~ push topmost value in register_c
) ~ wrap stack to array
˜ ~ deep flatten
¹<è ~ 1-indexed value of input in array
, ~ print & pop
(start to construct the group part)
XX ~ push 1 twice
Y8×SD ~ push 2 eight times (twice)
> ~ increment each value by 1
4 18×S ~ push 4 eighteen times (twice)
> ~ increment each value by one
66S ~ push 6 twice
ð15×S ~ push a space character 15 times
6 15×S ~ push 6 fifteen times
77S ~ push 7 two times
ð15×S ~ push a space character 15 times
7 15×S ~ push 7 fifteen times
)˜ ~ wrap stack to array and deep flatten
¹<è, ~ get 1-indexed value of input in array, then pop & print

```

Try it online!

# Answer
> 7 votes
## Mathematica, 77 bytes

```
e=ElementData;Which[56<#<72,"L",88<#<104,"A",1>0,{#~e~"Group",#~e~"Period"}]&

```

It would also be quite easy to use `ElementData` to determine whether the input is a Lanthanide or Actinide, but it would take about 20 more bytes.

# Answer
> 6 votes
# Python 2, ~~205~~ 136 bytes

-26 bytes thanks to @Dead Possum

```
def f(x):a=(x>71)+(x>99);print((((x-2*(x>1)-8*(x>4)-8*(x>12)+4*a-1)%18+1,(x-(x>17)-14*a)/18+(x>2)+(x>10)+1),'L'),'A')[88<x<104][56<x<72]

```

Try it online!

# Answer
> 3 votes
# PHP, 144 bytes

Note: uses IBM-850 encoding

```
$x=($a=$argn-1)<57|$a>70?$a>88&$a<103?A:0:L;foreach([16,19=>10,37=>10,92=>-14,110=>-14]as$l=>$m)$a>$l&&$a+=$m;echo$x?:$a%18+1 .~Ë.ceil(++$a/18);

```

Run like this:

```
echo 118 | php -nR '$x=($a=$argn-1)<57|$a>70?$a>88&$a<103?A:0:L;foreach([16,19=>10,37=>10,92=>-14,110=>-14]as$l=>$m)$a>$l&&$a+=$m;echo$x?:$a%18+1 .~Ë.ceil(++$a/18);';echo
> 18,7

```

# Explanation

Check whether input is within the ranges for `L` or `A`; the "exception" ranges. Then modify the input to fill the missing cells in the grid (or get rid of the extra cells). Finally, print the exception (unless that is falsy `0`) or convert the position to grid coordinates.

# Answer
> 3 votes
# Jelly, 57 bytes

```
“9Ḳ*!}ḣE’ṃ“¢£Æ¥Ø‘r2/;€"“ⱮḶıð’ḃ7¤µ⁵,12Ṭœṗ;"⁾LAṁ€15¤j“”$⁺³ị

```

Full program that prints the desired output.

**Try it online!** (A slightly modified program which prints all `input : output` may be seen here).

### How?

Builds a list of the 118 possible outputs and then picks the entry at the index of the input.

Some prep:

```
“9Ḳ*!}ḣE’ - base 250 number: 14334152882934570 (call this A)

“¢£Æ¥Ø‘   - a list using Jelly's code page: [1, 2, 13, 4, 18] (call this B)

“ⱮḶıð’    - base 250 number: 2354944025 (call this C)

```

The program (shortened by substituting `A`, `B`, and `C`) :

```
AṃBr2/;€"Cḃ7¤µ⁵,12Ṭœṗ;"⁾LAṁ€15¤j“”$⁺³ị - Main link: atomicNumber
AṃB                                    - number A with digits B: [1,1,18,18,1,2,13,18,1,2,13,18,1,18,1,18,1,2,4,18,1,2,4,18]
    2/                                 - pair-wise reduce with
   r                                   -     inclusive range: [[1],[18],[1,2],[13,14,15,16,17,18],[1,2],[13,14,15,16,17,18],[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18],[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18],[1,2],[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18],[1,2],[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]]
            ¤                          - nilad followed by link(s) as a nilad:
         C                             -     number C
          ḃ7                           -     converted to bijective base 7: [1,1,2,2,3,3,4,5,6,6,7,7]
        "                              - zip with:
      ,€                               -     pair each: [[1,1],[18,1],[[1,2],[2,2]],[[13,2],[14,2],[15,2],[16,2],[17,2],[18,2]],[[1,3],[2,3]],[[13,3],[14,3],[15,3],[16,3],[17,3],[18,3]],[[1,4],[2,4],[3,4],[4,4],[5,4],[6,4],[7,4],[8,4],[9,4],[10,4],[11,4],[12,4],[13,4],[14,4],[15,4],[16,4],[17,4],[18,4]],[[1,5],[2,5],[3,5],[4,5],[5,5],[6,5],[7,5],[8,5],[9,5],[10,5],[11,5],[12,5],[13,5],[14,5],[15,5],[16,5],[17,5],[18,5]],[[1,6],[2,6]],[[4,6],[5,6],[6,6],[7,6],[8,6],[9,6],[10,6],[11,6],[12,6],[13,6],[14,6],[15,6],[16,6],[17,6],[18,6]],[[1,7],[2,7]],[[4,7],[5,7],[6,7],[7,7],[8,7],[9,7],[10,7],[11,7],[12,7],[13,7],[14,7],[15,7],[16,7],[17,7],[18,7]]]
             µ                         - monadic chain separation (call the result x)
              ⁵                        - 10
               ,12                     - pair with 12: [10,12]            10↓ 12↓
                  Ṭ                    - truthy indexes: [0,0,0,0,0,0,0,0,0,1,0,1]
                   œṗ                  - partition x at the truthy indexes
                                       -     (the locations of the runs of L's and A's)
                              ¤        - nilad followed by link(s) as a nilad:

                       ⁾LA             -     ['L','A']
                          ṁ€15         -     mould each like 15: [['L','L','L','L','L','L','L','L','L','L','L','L','L','L','L'],['A','A','A','A','A','A','A','A','A','A','A','A','A','A','A']]
                      "                - zip with:
                     ;                 -     concatenation: [[[1,1],[18,1],[[1,2],[2,2]],[[13,2],[14,2],[15,2],[16,2],[17,2],[18,2]],[[1,3],[2,3]],[[13,3],[14,3],[15,3],[16,3],[17,3],[18,3]],[[1,4],[2,4],[3,4],[4,4],[5,4],[6,4],[7,4],[8,4],[9,4],[10,4],[11,4],[12,4],[13,4],[14,4],[15,4],[16,4],[17,4],[18,4]],[[1,5],[2,5],[3,5],[4,5],[5,5],[6,5],[7,5],[8,5],[9,5],[10,5],[11,5],[12,5],[13,5],[14,5],[15,5],[16,5],[17,5],[18,5]],[[1,6],[2,6]],'L','L','L','L','L','L','L','L','L','L','L','L','L','L','L'],[[[4,6],[5,6],[6,6],[7,6],[8,6],[9,6],[10,6],[11,6],[12,6],[13,6],[14,6],[15,6],[16,6],[17,6],[18,6]],[[1,7],[2,7]],'A','A','A','A','A','A','A','A','A','A','A','A','A','A','A'],[[4,7],[5,7],[6,7],[7,7],[8,7],[9,7],[10,7],[11,7],[12,7],[13,7],[14,7],[15,7],[16,7],[17,7],[18,7]]]

             µ⁵,12Ṭœṗ;"⁾LAṁ€15¤j“”$⁺³ị
                                  $    - last two links as a monad:
                               j“”     -     join with [''] (a workaround for no "flatten by 1")
                                   ⁺   - repeat last link (flatten once more): [[1,1],[18,1],[1,2],[2,2],[13,2],[14,2],[15,2],[16,2],[17,2],[18,2],[1,3],[2,3],[13,3],[14,3],[15,3],[16,3],[17,3],[18,3],[1,4],[2,4],[3,4],[4,4],[5,4],[6,4],[7,4],[8,4],[9,4],[10,4],[11,4],[12,4],[13,4],[14,4],[15,4],[16,4],[17,4],[18,4],[1,5],[2,5],[3,5],[4,5],[5,5],[6,5],[7,5],[8,5],[9,5],[10,5],[11,5],[12,5],[13,5],[14,5],[15,5],[16,5],[17,5],[18,5],[1,6],[2,6],'L','L','L','L','L','L','L','L','L','L','L','L','L','L','L',[4,6],[5,6],[6,6],[7,6],[8,6],[9,6],[10,6],[11,6],[12,6],[13,6],[14,6],[15,6],[16,6],[17,6],[18,6],[1,7],[2,7],'A','A','A','A','A','A','A','A','A','A','A','A','A','A','A',[4,7],[5,7],[6,7],[7,7],[8,7],[9,7],[10,7],[11,7],[12,7],[13,7],[14,7],[15,7],[16,7],[17,7],[18,7]]
                                    ³  - program's first input
                                     ị - index into the list

```

# Answer
> 2 votes
# Perl5, 202 bytes

```
$x=substr(" !2ABMNOPQRabmnopqr\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\301\302LLLLLLLLLLLLLLL\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\341\342KKKKKKKKKKKKKKK\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362",$ARGV[0],1);print$x=~/K/?"A":$x=~/L/?$x:(ord($x)&31).",".(ord($x)>>5)

```

# Answer
> 2 votes
# Ruby, 130 bytes

```
->a{(w=32767)[a-57]>0??L:w[a-89]>0??A:([[1,2],[20,8],[38,8],[107,32],[125,32]].map{|x,y|a>x&&a+=18-y};[(b=a%18)>0?b:18,~-a/18+1])}

```

First get the 'A' and 'L' with the bitmask trick, then try to fit into a 18\*7 rectangle and use a div/mod.

# Answer
> 2 votes
# Python 2, 137 bytes

```
lambda x:[(1+(x>2)+(x>10)+min((~-x/18),3)+(x>86),(x+(x>1)*15+((x>4)+(x>12))*10-((x>71)+(x>103))*14)%18+1),"AL"[89<x]][57<x<72or 89<x<104]

```

Try it online!

# Answer
> 2 votes
# Python 2, 115 bytes

```
def f(n):n+=([0,17]+[33]*3+[43]*8+[53]*45+[200]*14+[39]*18+[400]*14+[25]*15)[n];print[(n%18+1,n/18),'L','A'][n/200]

```

Try it online!

The idea is to div-mod the grid position to get the group and period. The grid position is the input `n` adjusted by a displacement to account for gaps and the L/A contraction. These are extracted from a list.

The Lanthanide and Actinide handling is ugly. These are assigned large displacements 200 and 400 that can be detected with `/200`. I'd like to put the characters `L` and `A` here, but then `n+=...` will add a char to a number, giving an error even if `n` is not used. If not for the 1-indexing, `divmod` could be used to refer to `n` only once, and then it could be replaced with its expression,

# Answer
> 2 votes
## JavaScript (ES7), ~~100~~ 98 bytes

```
f=(n,p=1,x=0,y=x+2*(p+2>>1)**2)=>(n-57&95)<15?n>71?'A':'L':n>y?f(n,p+1,y):[n-x-1>p/2?n-y+18:n-x,p]
```

```
<input type=number min=1 max=118 oninput=o.textContent=f(this.value)><pre id=o>
```

Explanation: The 'L' and 'A' series are special-cased, using some bitwise logic that saved me 3 bytes over direct comparisons. Otherwise the function recursively finds the period `p` containing the desired atomic number, the number of the last element in the previous period `x`, and the number of the last element in the period `y` which is computed each time by noting that the differences are 2, 2, 8, 8, 18, 18 i.e. repeated doubled square numbers. The group is then found by offsetting from the left or right of the table depending on whether the element lies under the Beryllium-Scandium diagonal or not.

# Answer
> 1 votes
# Python 2, ~~264~~ ~~227~~ 217 bytes

```
lambda x:((((((((((((((1,1),(18,1))[x>1],(x-2,2))[x>2],(x+8,2))[x>4],(x-10,3))[x>10],(x,3))[x>12],(x-18,4))[x>18],(x-36,5))[x>36],(x-54,6))[x>54],'L')[x>56],(x-68,6))[x>71],(x-86,7))[x>86],'A')[x>88],(x-100,7))[x>103]

```

Try it online!

Way too many brackets. It looks more like Brain-Flak.

# Answer
> 1 votes
## JavaScript (ES6), 136 bytes

```
n=>[...'112626ii2ff2fff'].reduce((p,i,j)=>(n-=parseInt(i,36))>0?n:+p?+(x='112233456L67A7'[j])?[p+(9258>>j&1?j>5?3:j>2?12:17:0),x]:x:p,n)

```

### Test

```
let f =

n=>[...'112626ii2ff2fff'].reduce((p,i,j)=>(n-=parseInt(i,36))>0?n:+p?+(x='112233456L67A7'[j])?[p+(9258>>j&1?j>5?3:j>2?12:17:0),x]:x:p,n)
```

```
<input oninput="o.innerHTML=f(+value)" type="number" min=1 max=118/>
<pre id="o"></pre>
```

# Answer
> 1 votes
# Excel, 192 bytes

Far from pretty. Borrows from existing Python answers

```
=SUBSTITUTE(SUBSTITUTE(IF(ABS(ABS(A1-80)-16)<8,IF(A1<80,"L","A"),MOD(A1-2*(A1>1)-8*(A1>4)-8*(A1>12)+4*((A1>71)+(A1>99)),18)&" ,"&1+(A1>2)+(A1>10)+(A1>18)+(A1>36)+(A1>54)+(A1>86)),0,18),118,10)

```

Struggling to handle the case where `MOD(x,18)=0` for Group value gracefully.

# Answer
> 0 votes
# Ruby, 116 bytes

```
->n{a=(17..143).map{|i|"#{[i%18+1,i/18]}"}
a[2..17]=a[21..30]=a[39..48]=[]
a[57]=[?L]*15
a[75]=[?A]*15
a.flatten[n]}

```

**Commented in test program**

```
f=->n{
a=(17..143).map{|i|"#{[i%18+1,i/18]}"} #Make an array with strings "[18,0]" to "[18,7]" (first value required as input is 1 indexed.)
a[2..17]=a[21..30]=a[39..48]=[]        #Delete "missing" elements from first three periods.
a[57]=[?L]*15                          #Replace position 57 in the table with a 15-element array ["L".."L"]
a[75]=[?A]*15                          #Replace the correct position in the table with a 15-element array ["A".."A"]
a.flatten[n]}                          #Flatten the array (break the two above elements into 15) and output element n of the array.

1.upto(118){|n|print n,f[n],$/}

```

# Answer
> 0 votes
# PHP, 120 bytes

```
echo(($n=--$argn)-56&95)<15?LA[$n>70]:(($n-=14*($n>88)+14*($n>56)-10*($n>11)-10*($n>3)-16*!!$n)%18+1).",".(($n/18|0)+1);

```

takes input from STDIN, run with `-nR`.

some bitwise magic for the Lanthanides and Actinides,
the `$n-=` part adds and subtracts offsets for the gaps and Lanthanides/Actinides,
the rest is simple mod/div.

An iterative port of Neil´s answer takes **108 bytes**:

```
for(;(95&71+$n=$argn)>14&&$n>$y+=2*(++$p+2>>1)**2;)$x=$y;
echo$p?$n-$x>$p/2+1?$n-$y+18:$n-$x:LA[$n>70],",$p";

```

# Answer
> 0 votes
# Perl, 169 bytes

```
90>($n-=14)&&($g=A)if($n=$v=pop)>88;58>($n-=14)&&($g=L)if$n>56;if(!$g){$c+=vec"\1\0\xe\xc0?\0".("\xff"x9)."?",$i++,1
while$c<$n;$p=1+($i-($g=$i%18||18))/18}say"$v,$g,$p"

```

Using:

```
perl -E '90>($n-=14)&&($g=A)if($n=$v=pop)>88;58>($n-=14)&&($g=L)if$n>56;if(!$g){$c+=vec"\1\0\xe\xc0?\0".("\xff"x9)."?",$i++,1 while$c<$n;$p=1+($i-($g=$i%18||18))/18}say"$v,$g,$p"' 103

```

# Answer
> 0 votes
# Jelly, ~~49~~ ~~43~~ ~~42~~ ~~41~~ 39 bytes

```
45“ÞØ\€a€⁶;l;i‘bx/€F’ḣ¹Sḃ18µV=“?I‘⁾LAxȯ

```

Try it online!

### Background

With the exception of lanthanides and actinides, the output will consist of an integer expressed in bijective base 18. For example, hydrogen corresponds to **1910 = 11b18**, helium to **3610 = 1Ib18**, and eka-radon/ununoctium/oganesson to **11410 = 7Ib18**.

We start by mapping all atomic numbers we can to the corresponding integers, while mapping lanthanides and actinides to those that correspond to lanthanum (**11110 = 63b18**) and actinium (**12910 = 73b18**).

To do this, we record the forward differences of the integers that represent the atoms. For example, the first is **1Ib18 \- 11b18 = Hb18 = 1710**, the second is **1** (as are all differences between consecutive elements of the unexpanded periodic table), the fourth (**B** to **Be**) is **2Db18 \- 22b18 = Bb18 = 1110**, and so on. To map all lanthanides and all actinides, we'll consider all differences between two lanthanides or to actinides (e.g., **La** to **Ce**) to be **0**.

To get the desired integer for an atomic number **n**, all we have to do is prepend **19** (hydrogen) to the differences and compute the sum of the first **n** elements of the resulting vector. The output is then simply displayed in bijective base 18, unless this would display **6 3** (lanthanides) or **7 3** (actinides). In the latter case, we simply replace the computed result with **L** or **A**.

Wrapped for horizontal sanity, the vector we have to encode looks as follows.

```
19 17  1  1 11  1  1  1  1  1  1  1 11  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
 1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
 1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  1  1  1  1  1  1  1  1  1  1  1  1
 1  1  1  1  1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  1  1  1  1  1  1  1  1
 1  1  1  1  1  1

```

After run-length encoding, we get the following.

```
19 1    17 1    1 2    11 1    1 7    11 1    1 44    0 14    1 18    0 14    1 15

```

To reduce the space required to encode the vector even more, we strip rightmost **1**'s (lengths) and add **1** to the runs.

```
20      18      2 2    12      2 7    12      2 44    1 14    2 18    1 14    2 15

```

Now we can reversibly convert these digit arrays from base 45 to integers.

```
20      18      92     12      97     12      134     59      108     59      105

```

All of these are smaller than **250**, so we can represent them with characters from Jelly's code page. Surrounded with  (literal start) and  (interpret as integer array), we get the Jelly literal

```
“ÞØ\€a€⁶;l;i‘

```

which appears verbatim in the code.

### How it works

```
45“…‘bx/€F’ḣ¹Sḃ18µV=“?I‘⁾LAxȯ  Main link. Argument: n (atomic number)

45                             Set the return value to 45.
  “…‘                          Yield [20,18,92,12,97,12,134,59,108,59,105].
     b                         Convert the integers in the array to base 45.
      x/€                      Reduce each resulting digit array (length 1 or 2)
                               by repetition, mapping [z] -> [z] and
                               [y,z] -> [y,…,y] (z times).
         F                     Flatten the result.
          ’                    Decrement, yielding the vector of length 118 from
                               the previous section.
           ḣ¹                  Head; take the first n elements of the vector.
             S                 Compute their sum.
              ḃ18              Convert to bijective base 18, yielding [p, g].
                 µ             Begin a new chain with argument [p,g].
                  V            Eval. The atom casts to string first, so [6,3]
                               , e.g., is mapped to 63, [7,18] to 718, etc.
                   =“?I‘       Compare the result with [63,73], yielding
                               [1,0] for lanthanides, [0,1] for actinides, and
                               [0,0] otherwise.
                        ⁾LAx   Repeat 'L' and 'A' that many times, yielding "L" for
                               lanthanides, "A" for actinides, and "" otherwise.
                            ȯ  Flat logical OR; replace "" with [p,g].

```

---
Tags: code-golf, kolmogorov-complexity, chemistry
---


title: A Complementary Quine

text:
# Question
Title: A Complementary Quine
Write a quine that outputs the complement of the source code from the smallest containing power of two. Here's an example:

```
IN : source
OUT: \r\x11\x0b\x0e\x1d\x1b

```

The largest code point in the string `"source"` is the letter `u`, which is 117. The smallest containing power of 2 would be 128, so all the code points are taken as complements from 128.

1. s: `128 - 115 = 13`. Code point 13 is a carriage return.
2. o: `128 - 111 = 17`. Code point 17 is "device control 1"
3. u: `128 - 117 = 11`. Code point 11 is a vertical tab.

And et cetera. Here's another example:

```
IN : R¡Ṡ
OUT: ᾮὟƠ

```

The largest code point is the character , which is 7776. The smallest containing power of 2 is 2^13 (8192), so each character is complemented from 8192.

All of the standard loopholes apply. A program must consist of some explicit data or code. A variable containing some data by default would be considered implicit data, and therefore not allowed.

If your language inevitably outputs a trailing newline, it can be disregarded.

# Answer
# Retina, ~~2~~ 1 byte

```
P

```

## Outputs

```
0

```

## Explained

`P` actually has no special meaning in retina, but retina treats it like a regex against the input, and counts the matches. As there's no input, there's no matches, so it returns `0`, which is the exact inverse of this.

Try it online!

This is using an older version of Retina, which outputs a newline with the zero. This is not the case in the latest version.
> 5 votes

# Answer
# Neim, 1 byte

```

```

**Try it online!**

Uses Neim's code-page, where  is byte **0xd0** (208) and the printed result, `0`, is byte **0x30** (48) which is as required (256-208).

is an instruction to get the nth element of a list. Both n and the list are implicit since they are missing and neim outputs implicitly too.
> 5 votes

# Answer
# RProgN 2, ~~17~~ 18 bytes

```
«` .S{c$256\-o}r.

```

## Output

```
U àÒ\x85\x9DÜÎËÊ¤Ó\x91\x83\x8EÒà

```

Where `\x` numbers are to be considered literal.

## Explained

```
«` .S{c$256\-o}r.
«                   # Push a function based on the remainder of the program and run it.
 ` .                # Append a space to the end, which stringifies it. As the stringification removes unnecessary spaces, this re-adds the leading one, making it a valid quine.
    S               # Convert it to a stack of characters.
     {        }r    # Replace each character based on a function.
      c             # Get the character code
       $256         # Push 256 literally.
           \-       # Flip them and subtract, giving 255 - char code, which is equivalent to the bitwise not of the char code.
             o      # Get the character this represents.
                .   # Reduce with Concatenation, turning it back into a string. Implicitely output.

```

Try it online!
> 3 votes

# Answer
# C, 178 bytes

```
char*u,*s="char*u,*s=%c%s%c;main(){char t[256];sprintf(t,s,34,s,34);for(u=t;*u;++u)*u=128-*u;puts(t);}";main(){char t[256];sprintf(t,s,34,s,34);for(u=t;*u;++u)*u=128-*u;puts(t);}

```

Try it online!
> 1 votes

# Answer
# JavaScript, 121 bytes

```
f=a=>[...a='f='+f].map(a=>(m=(a=a.charCodeAt())>m?a:m,a),m=0).map(a=>String.fromCharCode(2**-~(Math.log2(m)|0)-a)).join``

```

Try it online!
> 0 votes

# Answer
# Python 2, 93 bytes

```
s='s=%r;print"".join(chr(128-ord(i))for i in s%%s)';print"".join(chr(128-ord(i))for i in s%s)

```

Try it online!
> 0 votes

---
Tags: code-golf, quine
---


title: Array Escape - get out of there

text:
# Question
Title: Array Escape - get out of there
One day you awake only to find yourself caught in an array. You try to just walk out of there, taking one index at the time, but it seems there are other rules:

The array is completely filled with natural numbers.

* If you find yourself on an index `n`, you go to the index `array[n]`, except:
* If you find yourself on an index `n` which is a prime number, you take `array[n]` steps back

Example: You start on index `4`, in this array (start index is 0):

```
array = [1,4,5,6,8,10,14,15,2,2,4,5,7];
-----------------^ you are here

```

As the value of the field you are on is `8`, you go to the index `8` as the first step. The field you land on contains the value `2`. You then go to index `2` as your second step. As`2`is a prime number, you take 5 steps back, which is your third step. As there is no index `-3`, you successfully escaped the array in a total of 3 steps.

**Your task is:**

To write a program or function, which accepts an array and a start index as parameter, and outputs the amount of steps to escape the array. If you can't escape the array (e.g. `[2,0,2]` with start-index `2` =\> you constantly go from index `2` to `0`), output a falsy value. You may use one-based indexing or zero-based indexing, but please specify which you use.

**Test cases**

Input: `[2,5,6,8,1,2,3], 3`

Output: `1`

Input: `[2, 0, 2], 2`

Output: `false`

Input: `[14,1,2,5,1,3,51,5,12,3,4,41,15,4,12,243,51,2,14,51,12,11], 5`;

Output: `6`

The shortest answer wins.

# Answer
## Pyth, 31 Bytes

```
KlQ%tl-.u?}NUK?P_N-N@QN@QNKQEKK

```

The test cases

It uses zero to indicate a false value, the number of hops otherwise.
> 4 votes

# Answer
# Python, ~~161~~ 138 bytes

Credits for factorial.

```
g=lambda x:0**x or x*g(x-1)
f=lambda a,i,n=0,l=[]:(i<0)+(i>=len(a))and n or(0 if i in l else f(a,[a[i],i-a[i]][i and-g(i-1)%i],n+1,l+[i]))

```

Ideone it!

### How it works

Wilson's theorem is used for prime checking.

Loop detection by storing seen indices to an array (`l`) and checking whether current index is in `l`.
> 9 votes

# Answer
# Python, 107 bytes

```
import sympy
f=lambda a,i,n=0:0if n>len(a)else f(a,[a[i],i-a[i]][sympy.isprime(i)],n+1)if 0<=i<len(a)else n

```

Usage: `f(list, start)` ex: `f([2,5,6,8,1,2,3], 3)`

Returns `0` for loops (detected when `n > len(a)`)
> 6 votes

# Answer
# Matlab, 138 bytes

This a straighforward approach, using 1-based indices because Matlab uses 1-based indices by default. To count the number of steps we use a `for` loop counting from 1 to infinity(!). For the case were we cannot escape the array, we use a vector `v` to keep track of which entries we already visited. If we visit an entry twice, we know we are stuck in an unescapeable cycle. To see check whether we are outside of an array, we use the `try/catch` structure, which also catches out of bounds exceptions.

```
function r=f(a,i);v=a*0;v(i)=1;for k=1:Inf;if isprime(i);i=i-a(i);else;i=a(i);end;try;if v(i);r=0;break;end;v(i)=1;catch;r=k;break;end;end

```
> 5 votes

# Answer
## 05AB1E, 32 bytes

```
ï[U¯Xåi0,q}²gL<Xå_#X²XèXDˆpi-]¯g

```

**Explanation**

```
ï                                 # explicitly convert input to int
 [                            ]   # infinite loop
  U                               # store current index in X
   ¯Xåi0,q}                       # if we've already been at this index, print 0 and exit
           ²gL<Xå_#               # if we've escaped, break out of infinite loop
                   X²XèXDˆpi-     # else calculate new index
                               ¯g # print nr of indices traversed

```

Try it online
> 5 votes

# Answer
# CJam, 44 bytes

Expects `index array` on the stack.

```
:G\{_G,,&{G=_L#)0{_L+:L;_mp3T?-F}?}L,?}:F~o@

```

Try it online!

My first CJam answer, hence why it's so terrible and imperative...

```
:G\{_G,,&{G=_L#)0{_L+:L;_mp3T?-F}?}L,?}:F~o@
:G                                              Store the array as G
  \                                             Put the index first
   {                                  }:F~      The recursive F function
     G,,                                        Generate a 0..length(G) sequence
    _   &                            ?          Check that the index is contained
         {                        }             If so, then...
          G=                                    Get the value at the index
            _L#)                 ?              If the value is in L (`-1)` gives `0` which is falsy)
                0                               Return 0 (infinite loop)
                 {              }               Otherwise...
                  _L+:L;                        Store the value we're accessing in L (infinite loop check)
                        _mp3T?-                 Remove 3 if the number is prime
                               F                Then recursively call F
                                   L,           We escaped! Return the size of "L" (number of steps)
                                          o     Print the top value of the stack
                                           @    Tries to swap 3 elements, which will error out

```

(it is considered okay to crash after the correct output as printed, which is what the program here does)
> 4 votes

# Answer
# JavaScript (ES6), 100

Index base 0. Note: this function modifies the input array

```
(a,p)=>eval("for(s=0;1/(q=a[p]);++s,p=p>1&&p%i||p==2?p-q:q)for(a[p]=NaN,i=1;p%++i&&i*i<p;);q==q&&s")

```

*Less golfed*

```
(a,p)=>
{
  for(s = 0;
      1/ (q = a[p]);
      ++s)
  {
    a[p] = NaN; // mark visited position with NaN to detect loops
    for(i = 1; p % ++i && i*i < p;); // prime check
    p = p > 1 && p % i || p == 2 ? p-q : q;
  }
  return q==q && s // return false if landed on NaN as NaN != NaN
}

```

**Test**

```
F=
(a,p)=>eval("for(s=0;1/(q=a[p]);++s,p=p>1&&p%i||p==2?p-q:q)for(a[p]=NaN,i=1;p%++i&&i*i<p;);q==q&&s")

;[
 [[2,5,6,8,1,2,3], 3, 1]
,[[2, 0, 2], 2, false]
,[[14,1,2,5,1,3,51,5,12,3,4,41,15,4,12,243,51,2,14,51,12,11], 5, 6]
].forEach(t=>{
  var [a,b,k]=t, i=a+' '+b,r=F(a,b)
  console.log(r==k?'OK':'KO',i+' -> '+r)

})
```
> 4 votes

# Answer
# JAVA, ~~229~~ 218 Bytes

```
Object e(int[]a,int b){Stack i=new Stack();int s=0;for(;!(a.length<b|b<0);s++){if(i.contains(b))return 1>2;i.add(b);b=p(b)>0?b-a[b]:a[b];}return s;}int p(int i){for(int j=2;j<i/2;j++)if(i%j<1)return 0;return i<2?0:1;}

```

Thanks to Kevin, 11 bytes bites the dust.
> 4 votes

# Answer
## C, 121 bytes

Function `f` accepts array, starting index (0-based) and number of elements in the array, since there is no way how to test the end of an array in C (at least I don't know any).

```
p(n,i,z){return--i?p(n,i,z*i*i%n):z%n;}c;f(a,i,n)int*a;{return i<0||i/n?c:c++>n?0:i&&p(i,i,1)?f(a,i-a[i],n):f(a,a[i],n);}

```

Try it on ideone!

**Note:** `function p(n)` tests if `n` is prime or not. Credit for this goes to @Lynn and his answer for Is this number a prime?
> 3 votes

# Answer
## JavaScript, ~~121~~ 132 bytes

```
p=n=>t=i=>n%i&&n>i?t(i+1):(0<n&&n<=i?1:0),c=-1,a=>r=s=>(++c,0<=s&&s<a.length?(p(s)(2)?r(s-a[s]):0||([a[s],s]=[0,a[s]])[1]?r(s):0):c)

```

```
f=(p=n=>t=i=>n%i&&n>i?t(i+1):(0<n&&n<=i?1:0),c=-1,a=>r=s=>(++c,0<=s&&s<a.length?(p(s)(2)?r(s-a[s]):0||([a[s],s]=[0,a[s]])[1]?r(s):0):c));

let test_data = [[[1,4,5,6,8,10,14,15,2,2,4,5,7],4],
                 [[2,5,6,8,1,2,3],3],
                 [[2,0,2],2],
                 [[14,1,2,5,1,3,51,5,12,3,4,41,15,4,12,243,51,2,14,51,12,11],5]];
for (test of test_data) {
    c = -1;
    console.log(f(test[0])(test[1]));
}
```

edit 1: oops, missed the bit about returning number of steps. fix coming soonish.

edit 2: fixed
> 3 votes

# Answer
# Racket, ~~183~~ 156 bytes

Probably more bytes savable with further golfing, but that's it for me. :)

```
(require math)(define(e l i[v'()][g length])(cond[(memq i v)#f][(not(< -1 i(g l)))(g v)][else(e l((λ(a)(if(prime? i)(- i a)a))(list-ref l i))(cons i v))]))

```

Complete module with test suite with cleaner function:

```
#lang racket

(require math)

(define (e l i [v'()] [g length])
  (cond
    [(memq i v) #f]
    [(not (< -1 i (g l))) (g v)]
    [else (e l
             ((λ (a) (if (prime? i)
                         (- i a)
                         a))
              (list-ref l i))
             (cons i v))]))

(module+ test
  (require rackunit)
  (define escape-tests
    '((((2 5 6 8 1 2 3) 3) . 1)
      (((2 0 2) 2) . #f)
      (((14 1 2 5 1 3 51 5 12 3 4 41 15 4 12 243 51 2 14 51 12 11) 5) . 6)))
  (for ([t escape-tests])
    (check-equal? (apply e (car t)) (cdr t) (~a t))))

```

Run it like `raco test e.rkt`

Major kudos for @cat discovering the undocumented `prime?` function.
> 3 votes

# Answer
## Java, ~~163~~ 160 bytes

```
boolean p(int n){for(int i=2;i<n;)if(n%i++==0)return 0>1;return 1>0;}
int f(int[]a,int n){return n<0||n>=a.length?1:p(n)?n<a[n]?1:1+f(a,a[n-a[n]]):1+f(a,a[n]);}

```

`p(n)` is for prime testing, `f(a,n)` is for the escape function. Usage:

```
public static void main(String[] args) {
    int[] array = {14,1,2,5,1,3,51,5,12,3,4,41,15,4,12,243,51,2,14,51,12,11};
    System.out.println(f(array, 5));
}

```

Ungolfed version:

```
static boolean isPrime(int n) {
    for (int i = 2; i < n; i++) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

static int escape(int[] array, int n) {
    if (n < 0 || n >= array.length) {
        return 1;
    } else if (isPrime(n)) {
        if (n < array[n]) {
            return 1;
        } else {
            return 1 + escape(array, array[n - array[n]]);
        }
    } else {
        return 1 + escape(array, array[n]);
    }
}

```
> 2 votes

# Answer
# Perl 6, 85 bytes

```
->\n,\a{{.[+a].defined??0!!+$_}(lazy n,{.is-prime??$_- a[$_]!!a[$_]}...^!(0 <=* <a))}

```

Explanation:

```
lazy n, { .is-prime ?? $_ - a[$_] !! a[$_] } ...^ !(0 <= * < a)

```

This is a lazy sequence of the indices traversed according to the rule. If the index eventually exceeds the input array bounds (the `!(0 <= * < a)` condition), the sequence is finite; otherwise, the indices cycle infinitely.

That sequence is fed to the internal anonymous function:

```
{ .[+a].defined ?? 0 !! +$_ }

```

If the sequence is defined at the index given by the size of the input array, it must have entered an infinite cycle, so `0` is returned. Otherwise, the size of the sequence `+$_` is returned.
> 1 votes

# Answer
# Perl 5, 107 + 1 (`-a`) = 108 bytes

```
for($i=<>;!$k{$i}++&&$i>=0&&$i<@F;$s++){$f=0|sqrt$i||2;1while$i%$f--;$i=$f?$F[$i]:$i-$F[$i]}say$k{$i}<2&&$s

```

Try it online!

0-based list. Returns false (blank) if the list is unescapable.
> 1 votes

---
Tags: code-golf, number, array, number-theory, primes
---


title: Tips for golfing in Röda

text:
# Question
Title: Tips for golfing in Röda
Röda is a stream-based scripting language created by fergusq.

What general tips do you have for golfing in Röda? I'm looking for ideas that can which can be applied to code-golf problems and which are also at least somewhat specific to Röda (e.g. "remove comments" is not an answer).

Please post one tip per answer.

# Answer
> 7 votes
# Use underscores

This is probably the most important tip. Nearly every golfed Röda program uses underscores.

The underscore syntax is syntactic sugar for `for` loops. The following lines of code are equivalent:

```
ls""|fileLength x for x|sort|pull
ls""|fileLength _|sort|pull

```

Each underscore adds a new variable to an invisible `for` loop that is around the statement. The loop pulls one value from the stream for each variable/underscore and then repeats, until no values are left.

Underscores can be used anywhere in statements:

```
a[x:y+1]=[1]*(1+y-x) /* Sets range x..y (inclusive) */
seq x,y|a[_]=1       /* 6 bytes less */

```

If you must refer to the same underscore value more than once, or use the values in reverse order, you can put a number after the underscore:

```
a|[_^_1]  /* maps x to x^x */
a|[_2-_1] /* maps each pair (x,y) to y-x, eg. [1,2,4,8] -> [1, 4] */

```

# Answer
> 3 votes
# Some semicolons/newlines are optional

When writing Röda code, it is generally recommended to use newlines or semicolons to separate all statements. However, when golfing, it is worth to know that not all semicolons are really required.

Here's an incomplete list of places where semicolons/newlines are **optional**. Most of them do not apply when the following statement begins with an operator (`(`, `[`, `+`, etc.).

* After assignments
* After function calls, when there's at least one argument (eg. `f x`) **or** when parentheses are used (eg. `f()`)
* Everywhere, if the next line/statement would begin with `|`, `)`, `]` or `}`

If the next statement begins with an operator, the semicolon/newline is **optional** if

* The statement is a function call and parentheses are used, eg `{f(x)[y]}` is same as `{f(x);[y]}`. This works only in statement context, not when the function call is an expression.
* The statement is an assignment and parentheses are used, eg `x=(y)[z]` is same as `x=(y);[z]` (that is not same as `x=((y)[z])`).

And here are some places where the newlines are unfortunately **required**:

* After `++` and `--`.
* After `[...]`.

It is often possible to save bytes by reorganizing assignments. For example:

```
a=0;b=""c=[""]
b=""c=[b]a=0

x=f()y=i;z=a[0]
x=f()z=a[0]y=i

```

# Answer
> 1 votes
# Use suffix control structures

It is almost **never** optimal not to use suffix statements, as you can use `{...}` in place of `do...end`.

Some examples:

```
x|unless[not(_ in y)]do[0]else[1]done
x|[0]unless[not(_ in y)]else[1]

if[p<0]do c+=p;a-=p done
{c+=p;a-=p}if[p<0]

```

# Answer
> 1 votes
# Use the stream for input

In cases where the input is a list of elements, it can be beneficial to pull the values from the stream instead of getting them as an array.

In most of the cases the array elements are iterated by pushing them to the stream and then iterating it using a `for` loop (or an underscore). As the elements are iterated from the stream anyway, why not *define* that they should be there from the beginning?

For example, to calculate the sum of the squares of the numbers in input:

```
{|a|a|[_^2]|sum} /* Removing a redundant argument */
{[_^2]|sum}      /* saves 5 bytes */

```

# Answer
> 1 votes
# Using ```` strings

In `""` strings, you will have to escape certain characters in order to use them. For example, to print the backslash, you would have to have a string like `"\\"`. There is one added byte for escaping the backslash. However, if you use ````, you do **not** have to escape this character and can save one byte.

```
print"\\"     /* 9 bytes */
print`\`      /* 8 bytes */

```

---

Not just that, you can encode variables and expressions inside of ```` strings using `$variableName` or `${expression}`, a feature not present in `""` strings.

<sub>We are outputting the string `"a"` concatenated with the value of the variable `b` with a trailing newline in these examples.</sub>

```
["a",b,"      /* 11
"]               bytes   */
[`a$b         /* 8
`]               bytes; encodes b in the string using $b */

```

# Answer
> 1 votes
# Use `,` instead of `and`

Conditions in Röda are streams, and can consist of multiple values. These values are reduced to one boolean value with `and`.

This means that you can replace `and` with `,` in conditions to push multiple values to the stream:

```
x if[a and b]
x if[a,b]

```

# Empty condition is truthy

It is also possible to have a condition that contains no values, which is truthy.

```
x while true
x while[]

```

# Answer
> 1 votes
The parentheses are optional in the statement context. This applies even if the argument begins with an operator. For example, `[a()|sqrt-_]` is shorter than `[a()|sqrt(-_)]`. The parentheses after `a` are mandatory, as `a` is in the expression context, not in the statement context.

However, writing `[a()|sqrt(_+1)*2]` is not possible, and extra parentheses are needed to help the parser: `[a()|sqrt((_+1)*2)]`. Often it is possible to rewrite such expression so that it doesn't begin with a parenthesis: `[a()|sqrt 2*(_+1)]`

# Answer
> 1 votes
# Use `,` instead of `..` in `[]`/`push` statements

> Related: Use `,` instead of `and`

The `push` function (as well as the `print` function) can take any number of arguments, and outputs each one of them with no delimiter.

So that means something like this

```
["a"..b]        /*8 bytes (string "a" concatenated with variable b)*/

```

can be shortened into just

```
["a",b]         /*7 bytes*/

```

saving 1 byte.

# Answer
> 1 votes
# `[]`/`push` \> `print`

Never use `print` statements. `[]` push statements are always golfier. The difference between `print` and `push` is that the former outputs a trailing newline while the latter doesn't. However, this can be circumvented.

```
print"a"              /* 8 bytes */
["a                   /* 6 bytes; uses a literal newline */
"]

print"a",b            /* 10 bytes */
[`a$b                 /* 8 bytes; uses a literal newline and `` strings */
`]

```

# Answer
> 1 votes
# Write replacement lists in form `*"...;..."/";"`

The `replace` function takes normally a list of strings as arguments. However, if the list is very long, it is beneficial to simply store the regex/replacement pairs in a string and then split the string and use the star operator:

```
replace"a","b","c","d"
replace*"a;b;c;d"/";"

```

---
Tags: code-golf, tips
---