title: How long ago was this?

text:
# Question
Title: How long ago was this?
## The Rules

* Each submission must be a full program.
* The program must take input as two comma-separated dates in the form `YYYY-MM-DD`, and print the number of days that has passed since the second date to STDOUT as if today was the first date (if the second date would be in the future, output a negative number) plus an optional trailing newline, and nothing else. Assume both dates are in the Gregorian calendar.
* The program must not write anything to STDERR.

Note that there must be an interpreter so the submission can be tested.
* Submissions are scored in *bytes*, in an appropriate (pre-existing) encoding, usually (but not necessarily) UTF-8. Some languages, like Folders, are a bit tricky to score - if in doubt, please ask on Meta.
* This is , so shortest code wins

## Examples

**Input:**

```
2015-12-03,2015-12-01
```

**Output:**

```
2
```

**Input:**

```
2015-12-03,2014-12-01
```

**Output:**

```
367
```

**Input:**

```
2015-12-03,2013-12-03
```

**Output:**

```
730
```

# Answer
# TeaScript, 24 bytes

```
((a=D.parse)×-a(y©/864e5

```

Uses `Date.parse` to parse the date, then get's the difference and divides.

Try it online

## Explanation && Ungolfed

```
((a=D.parse)(x)-a(y))/864e5

               // Implicit: x is first date
               // y is second date
(
 (a=D.parse)   // Assign Date.parse to 'a'
 (x)           // Run Date.parse with first date
 -a(y)         // Subtract Date.parse run with second date
)/864e5        // Divide by 86,400,000

```
> 1 votes

# Answer
# Bash + GNU utilities, 37

```
tr , \\n|date -f- +%s|dc -e??-86400/p

```

`tr` replaces the comma with a newline. `date` reads the newline separated dates and outputs the number of seconds since the Unix epoch that the passed-in date represents. These numbers are then put on the `dc` stack. Then its a simple matter of subtraction and divide by (24\*60\*60). In this case, `dc` stack-based RPN arithmetic evaluation is better than `bc` or bash `$( )`, mostly because the subraction-before-division needs no parentheses.

Input via STDIN:

```
$ echo 2015-12-3,2015-12-1 | ./longago.sh
2
$ echo 2015-12-3,2014-12-1 | ./longago.sh
367
$ echo 2015-12-3,2013-12-3 | ./longago.sh
730
$

```
> 13 votes

# Answer
# Julia, 67 bytes

```
print(Int(-diff(map(i->Date(i,"y-m-d"),split(readline(),",")))[1]))

```

Ungolfed:

```
# Read a line from STDIN
r = readline()

# Split it into two character dates
s = split(r, ",")

# Convert each to a Date object
d = map(i -> Date(i, "y-m-d"), s)

# Compute the difference in dates (first-second)
f = diff(d)[1]

# Convert the Base.Date.Day object to an integer
# Negate to get second-first
i = Int(-f)

# Print to STDOUT
print(i)

```
> 4 votes

# Answer
## Scala, ~~166~~ ~~139~~ ~~120~~ ~~116~~ 92 bytes

```
print(args(0).replace('-','/').split(",").map(java.util.Date.parse(_)/86400000).reduce(_-_))

```

Usage: `scala [source filename].scala [date1],[date2]`

*Note: The third version (120 bytes) and on uses a deprecated API. It still compiles and works fine.* *Note2: Thanks to the commenters below for the great advice!*
> 4 votes

# Answer
# Ruby, ~~69~~ ~~66~~ ~~65~~ ~~57~~ 55 bytes

```
a=->l{Time.gm *$F[l,3]};p (a[0]-a[3]).div 86400

```

47 bytes + 8 bytes for command line option. Thanks to Dane Anderson, saved 2 bytes.

**57 bytes**

```
p (Time.gm(*$F[0,3])-Time.gm(*$F[3,3])).div 86400

```

49 bytes code + 8 bytes for command line option. Saved 8 bytes with manatwork's suggestion.

**65 bytes**

```
a,b=gets.split(?,).map{|i|Time.gm *i.split(?-)};p (a-b).div 86400

```

**66 bytes**

```
a,b=gets.split(?,).map{|i|Time.new *i.split(?-)};p (a-b).div 86400

```

**69 bytes**

```
a,b=gets.split(',').map{|i|Time.new *i.split('-')};p (a-b).to_i/86400

```

Test it online

**Ungolfed**

```
a = -> l {
  Time.gm *$F[l,3]       # Anonymous method to parse time
}
p (a[0]-a[3]).div 86400  # Subtracts two times and divides by 24*60*60

```

**Usage:**

```
ruby -naF[,-] -e 'a=->l{Time.gm *$F[l,3]};p (a[0]-a[3]).div 86400' <<< '2015-12-3,2013-12-3'

=> 730

```
> 3 votes

# Answer
# Javascript ES6, 63 bytes

Tested in chrome.

```
alert(((p=Date.parse)((a=prompt().split`,`)[0])-p(a[1]))/864e5)

```
> 2 votes

# Answer
# Japt, 41 bytes

```
A=K$.parse)(($B=Uq',  g0)-$A($Bg1))/864e5

```

So far this is the best I can get it as all the variables and `$` and parenthesis really kill the byte count.

Try it online

## Explanation

```
             // Implicit: U is set to input
A=K$.parse)  // Set variable A to date parsing function
(($B=Uq',    // Set B to input split by ,
  g0)        // Get the first date and parse
-            // Subtract...
$A(          // Parse this date...
   $Bg1      // Get's second date
))/864e5     // Divides by 86,400,000

```
> 2 votes

# Answer
# MATLAB, ~~41~~ 31 bytes

```
disp(-diff(datenum(input(''))))
{'2015-12-03', '2014-12-22'}
   346

```

Input must be a comma-separated cell array. `datenum` converts the input cell into a 2x1 numeric array with the time stamp. `diff` takes the difference between the two.

---

**Old solution, 41 bytes**:

```
disp(-diff(datenum(strsplit(input('')))))

```

Input must be a comma-separated string:

```
disp(-diff(datenum(strsplit(input('')))))
'2015-12-03, 2014-12-22'
   346

```

The curious ways of programming. This works because of MATLAB's implicit casting between datatypes.

The output from `strsplit(input(''))` is a cell of strings. You cannot use `diff` on a cell, but fortunately, `datenum` works, and it actually casts the cell input back to a 2x1 numeric array, making `diff` possible to use.

You can specify a whole lot of delimiters in `strsplit`, but comma is the default one. Also, the default input to `datenum` is on the format `yyyy-mm-dd`. For those reasons, a lot of specifications such as: datenum(s,'yyyy-mm-dd') are avoided, saving a whole lot of bytes.

For the record, this would be 21 bytes if I could use a function:

```
@(s)-diff(datenum(s))

```
> 2 votes

# Answer
# PHP, 63 ~~64~~ ~~77~~ bytes

Found that the classic approach is shorter than the OOP one:

```
$x=fgetcsv(STDIN);$s=strtotime;echo($s($x[0])-$s($x[1]))/86400;

```

Reads the comma separated string from `STDIN`.

---

The straight forward OOP way (**77 bytes**):

```
$x=fgetcsv(STDIN);echo(new DateTime($x[0]))->diff(new DateTime($x[1]))->days;

```

---

**Edits**

* *Saved* **13 bytes** by using `strtotime` instead of `DateTime`.
* *Saved* **1 byte** by storing `strtotime` in a variable. Thanks to Blackhole.
> 2 votes

# Answer
# Excel, 25 bytes

```
=LEFT(A1,10)-RIGHT(A1,10)

```

Excel automatically handles the strings as dates.
> 2 votes

# Answer
# Python 2, ~~109~~ 113 bytes

```
import datetime as d
j=[d.date(*[int(k) for k in g.split('-')]) for g in raw_input().split(',')]
print j[0]-j[1]

```
> 1 votes

# Answer
# VBA, 69 bytes

```
Function x(s)
g=Split(s, ",")
x=CDate(g(0))-CDate(g(1))
End Function

```
> 1 votes

# Answer
# psql, 75 bytes

(74 characters code + 1 character command line option)

```
\prompt i
select split_part(:'i',',',1)::date-split_part(:'i',',',2)::date

```

`psql` is PostgreSQL's interactive terminal. To respect the “Each submission must be a full program.” rule, the code reads the input itself.

Sample run:

```
bash-4.3$ psql -tf how-long-was-this.sql <<< '2015-12-3,2013-12-3'
      730

```
> 1 votes

# Answer
## PowerShell v2+, ~~50~~ 44 Bytes

```
$a,$b=$args-split','|%{date $_};($a-$b).Days

```

Takes input argument as a string, splits it on the comma, then pipes the array via a built-in alias `date` short for `Get-Date` to convert our strings into .NET datetime format. Those two dates then get stored simultaneously into `$a` and `$b`. We then use an overloaded-subtraction-operator to subtract the second from the first, and output the `.Days` thereof.

Golfed 6 bytes thanks to TessellatingHeckler.

Technically non-competing, as it doesn't have an online interpreter available, since the FOSS implementation of PowerShell, Pash, is around PowerShell v0.5. It doesn't support `-split` yet, let alone the complex .NET date functionality.
> 1 votes

# Answer
## MATL, 5 bytes

```
iPYOd

```

This is the same as StewieGriffin's answer, except I used `flip` then `diff` rather than `diff` then negating the result.

Full explanation, with corresponding Matlab functions:

```
i   %// input(''), get input
P   %// flip, flips the array
YO  %// datenum, converts date string into an integer
d   %// diff, finds the difference between dates

```
> 1 votes

# Answer
# Japt, 13 bytes

```
£ÐXÃr- zHÑ7e5

```

Try it
> 1 votes

# Answer
# JavaScript, ~~58~~ 53 bytes thanks to @targumon!

```
n=>(new Date((a=n.split`,`)[0])-new Date(a[1]))/864e5

```

Older version:

```
n=>(new Date((a=n.split(','))[0])-new Date(a[1]))/86400000

```

My submissions seem to have a reputation of being boring.
> 1 votes

# Answer
# Jolf, 33 bytes

Only works in Chrome. Noncompeting, since language updates postdate question. I'll add a more thorough explanation later.

```
$S=$viGi', mDN~DH r}/m4SmeP"864"5

```

## “Explanation”

```
$S=$viGi', mDN~DH r}
$S=$                 sets S equal to
    viGi',           take string input and reassign it to the comma-split input
           mD      } map with this function
             N~DH r  return the time of the date of H (element)

/m4SmeP"864"5
/             divide
 m4S           subtraction applied to S (S[0] - S[1])
    meP"864"5  and 864 * 10 ^ 5 (thanks to Super Jedi for his nice constant)
              implicit output

```
> 0 votes

# Answer
## MATLAB, 59 bytes

```
s=strsplit(input(''),',');disp(datenum(s{1})-datenum(s{2}))

```

Very straightforward approach: input has to be given as a string from the command window. The input string is then split and the number of days between the dates (and nothing else) is calculated from the serial date numbers. I'm quite sure there is a way to avoid the need for calling datenum twice though...
> 0 votes

# Answer
# jq, 50 bytes

(49 characters code + 1 character command line option)

```
./","|map(.+"T0:0:0Z"|fromdate)|(.[0]-.[1])/86400

```

Sample run:

```
bash-4.3$ ~/bin/jq -R './","|map(.+"T0:0:0Z"|fromdate)|(.[0]-.[1])/86400' <<< '2015-12-3,2013-12-3'
730

```

On-line test (Passing `-R` through URL is not supported – so input passed as string "2015-12-3,2013-12-3".)
> 0 votes

# Answer
## T-SQL + SQLCMD, 51 bytes

```
PRINT DATEDIFF(D,RIGHT('$(i)',10),LEFT('$(i)',10))

```

Tested with SQL Server 2008R2. The $(i) is replaced with the input provided as a command line argument.

Sample run:

```
sqlcmd -i script.sql -v i="2015-12-08,2016-01-01"
-24

```
> 0 votes

# Answer
## Perl, 91 86 + 2 for np flags, 88 bytes

use Date::Calc qw(Delta\_Days);($a,$b)=split(/,/);$\_=Delta\_Days(split(/-/,$b),split(/-/,$a))

```
use Date::Parse;$_=str2time((split(/,/,$_))[0])-str2time((split(/,/,$_))[1]);$_/=86400

```

Example

```
$ echo 2015-12-3,2015-12-1 | perl -npe 'use Date::Parse;$_=str2time((split(/,/,$_))[0])-str2time((split(/,/,$_))[1]);$_/=86400'
2

```
> 0 votes

# Answer
## Mathematica, 61 bytes

```
Print@First[#-#2&@@DateObject/@InputString[]~StringSplit~","]

```

Basic date subtraction.
> 0 votes

# Answer
## Mathematica, 56 bytes

```
Print@#&@@-DateDifference@@InputString[]~StringSplit~","

```

Most (all?) date functions will try to parse string inputs into dates automatically.
> 0 votes

# Answer
# C# .NET, 148 bytes

```
using System;class P{static void Main(string[]a){Console.Write((DateTime.Parse(a[0].Substring(11,10))-DateTime.Parse(a[0].Substring(0,10))).Days);}}

```

Try Online
> 0 votes

# Answer
# C (gcc), ~~225~~ 199 bytes

-25 bytes thanks to ceilingcat! Replacing an array of numbers with a string of wide-characters is some proper black-magic

-1 byte by adding an additional character to the start of the string, allowing for indexing with \[m\] instead of \[m-1\]

```
a,b,d,e,f;i(m,y){return(a=y-1)*365+a/4-a/100+a/400+L"\0\37;Zx\x97µÔóđİŎ"[m]+(m>1&(y%100*!(y%4)||y%400<1));}main(c){scanf("%d-%d-%d,%d-%d-%d",&a,&b,&c,&d,&e,&f);printf("%d",i(b,a)-i(e,d)+c-f);}

```

Try it online!

Perhaps the code could be shortened by using \<time.h\>, but not using it makes for a fun challenge. The difference between dates is calculated using a golfed version of this code.

Un-golfed:

```
a,b,d,e,f;
i(m,y){
    return(a=y-1)*365 /*Num days in y-1 years*/
        +a/4-a/100+a/400 /*Add previous years' leap days*/
        +L" \0\37;Zx\x97µÔóđİŎ"[m] /*Add days this year until month*/
        +(m>1&(y%100*!(y%4)||y%400<1)); /*Add this year's leap day*/
}
main(c){
    scanf("%d-%d-%d,%d-%d-%d",&a,&b,&c,&d,&e,&f);
    printf("%d",i(b,a)-i(e,d)+c-f);
}

```
> 0 votes

---
Tags: code-golf, date
---


title: Factorials and never ending cycles!

text:
# Question
Title: Factorials and never ending cycles!
As you may know it, the factorial of a positive integer `n` is the product of all the positive integers which are equal or smaller to `n`.

For instance :

```
6! = 6*5*4*3*2*1 = 720
0! = 1

```

We will now define a special operation with an irrelevant name like `sumFac`:

Given a positive integer `n`, `sumFac(n)` is the sum of the factorials of the digits.

For instance :

`sumFac(132) = 1! + 3! + 2! = 9`

## Task

Your mission, whether or not you choose to accept it, is to return the sequence (potentially infinite) of the applications of `sumFac` to an integer given in input.

Example : `132 -> 132, 9, 362880, 81369, 403927, ...`

But that's not all! Indeed, the applications of `sumFac` will eventually create a cycle. You must also return this cycle!

If your language has a built in factorial you can use it. I'm not picky about the return type, you just have to return the sequence of sumFac applications and the cycle in a format understandable by a human.

EDIT : To help you visualize better what should the output look like I copied Leaky Nun's just below:

```
[132, 9, 362880, 81369, 403927, 367953, 368772, 51128, 40444, 97, 367920, 368649, 404670, 5810, 40442, 75, 5160, 842, 40346, 775, 10200, 6, 720, 5043, 151, 122, 5, 120, 4, 24, 26, 722, 5044, 169, 363601, 1454]

```

You just need to stop the sequence when the cycle is about to start for the second time!

But this is code-golf so the shortest answer in bytes wins!

# Answer
# Jelly, 6 bytes

```
D!SµÐĿ
    ÐĿ  Repeat until the results are no longer unique. Collects all intermediate results.
D           Convert from integer to decimal (list of digits)
 !          Factorial (each digit)
  S         Sum

```

Try it online!

I don't see any other way to make it shorter other than to do as told.

## Specs

* Input: `132` (as command-line argument)
* Output: `[132, 9, 362880, 81369, 403927, 367953, 368772, 51128, 40444, 97, 367920, 368649, 404670, 5810, 40442, 75, 5160, 842, 40346, 775, 10200, 6, 720, 5043, 151, 122, 5, 120, 4, 24, 26, 722, 5044, 169, 363601, 1454]`
> 21 votes

# Answer
# Python 2, 88 bytes

```
import math
f=lambda x,l=[]:l*(x in l)or f(sum(math.factorial(int(i))for i in`x`),l+[x])

```

Try it online!
> 10 votes

# Answer
# 05AB1E, 12 bytes

```
[DˆS!O©¯så#®

```

Try it online!

**Explanation**

```
[               # infinite loop
 Dˆ             # add a copy of current value to the global list (initialized as input)
   S            # split current number to digits
    !O          # calculate factorial of each and sum
      ©         # save a copy in register
       ¯så#     # if the current number is in the global list, exit loop
           ®    # retrieve the value from the register for the next iteration
                # implicitly output the global list

```
> 9 votes

# Answer
# Brachylog, 17 bytes

```
g:I{tẹḟᵐ+}ᵃ⁾L¬≠Lk

```

Try it online!

### Explanation

```
g:I{     }ᵃ⁾         Accumulate I (a variable) times, with [Input] as initial input:
    t                  Take the last integer
     ẹḟᵐ+              Compute the sum of the factorial of its digits
            L        The result of the accumulation is L
            L¬≠      Not all elements of L are different
               Lk    Output is L minus the last one (which is the start of the loop)

```
> 8 votes

# Answer
# Wolfram Language, ~~62~~ ~~60~~ 56 bytes

```
Most@NestWhileList[Tr[IntegerDigits@#!]&,#,UnsameQ,All]&

```

It is really too bad that Wolfram Language has such abominably long function names. \*Sigh\*

**Explanation:**

```
Most[NestWhileList[Tr[IntegerDigits[#]!]&,#,UnsameQ,All]]&
                      IntegerDigits[#]                     (*Split input into list of digits*)
                                      !                    (*Factorial each element in the list*)
                   Tr[                 ]&                  (*Sum the list together*)
     NestWhileList[                      ,#,UnsameQ,All]   (*Iterate the function over itself, pushing each to a list, until a repeat is detected*)
Most[                                                   ]& (*Remove the last element in the list*)

```
> 8 votes

# Answer
# ClojureScript, ~~146~~ 109 bytes

```
#(loop[n[%]](let[f(apply +(for[a(str(last n))](apply *(range 1(int a))))](if(some #{f}n)n(recur(conj n f)))))

```

Yikes, that is a monstrosity. Someone please help me golf this...

Thanks `@cliffroot` for shaving off a whopping 37 bytes!

This is an anonymous function, to run the function, you have to do this:

```
(#(...) {arguments})

```

TIO doesn't have ClojureScript, so here's a link to a ClojureScript REPL.

Here's a link to a Clojure program which prints the last element in the list from 0 to 1000.

Here's the output for `9999`:

```
[9999 1451520 269 363602 1455 265 842 40346 775 10200 6 720 5043 151 122 5 120 4 24 26 722 5044 169 363601 1454]

```

I have a strong suspicion that all numbers must eventually settle at `1` or the loop `[169 363601 1454]`.

## Ungolfed code:

```
(defn fact-cycle [n]
  (loop [nums [n]]
    (let [fact-num
          (let [str-n (str (last nums))]
            (apply +
              (for [a (range (count str-n))]
                (apply *
                  (range 1
                    (inc (int (nth str-n a))))))))]
      (if (some #{fact-num} nums) nums
        (recur
          (conj nums fact-num))))))

```

Explanation coming soon!
> 6 votes

# Answer
## JavaScript (ES6), ~~91~~ 89 bytes

*Saved 2 bytes thanks to fəˈnɛtɪk*

It turns out to be quite similar to the other JS answer.

```
f=(n,x=!(a=[n]))=>n?f(n/10|0,x+(F=n=>n?n--*F(n):1)(n%10)):~a.indexOf(x)?a:f(x,!a.push(x))

```

```
f=(n,x=!(a=[n]))=>n?f(n/10|0,x+(F=n=>n?n--*F(n):1)(n%10)):~a.indexOf(x)?a:f(x,!a.push(x))

console.log(f(132))
```
> 6 votes

# Answer
# Perl 6, 64 bytes

```
{my@a;$_,{[+] .comb.map:{[*] 2..$_}}...^{$_∈@a||!@a.push: $_}}

```

Try it

## Expanded:

```
{

  my @a;             # array of values already seen

  $_,                # seed sequence with the input

  {
    [+]              # reduce using &infix:<+>
      .comb          # the digits of $_ (implicit method call)
      .map:          # do the following for each
      {
        [*] 2..$_    # get the factorial of
      }
  }

  ...^               # keep generating values until
                     # (｢^｣ means throw away the last value when done)

  {
      $_ ∈ @a        # is it an elem of @a? (｢∈｣ is shorter than ｢(cont)｣)

    ||               # if it's not

      !              # boolean invert so this returns False
        @a.push: $_  # add the tested value to @a
  }
}

```

Every line above that has `{` starts a new bare block lambda with an implicit parameter of `$_`.

I used `[*] 2..$_` instead of `[*] 1..$_` purely as a micro optimization.
> 5 votes

# Answer
# JavaScript, 92 bytes

Thanks @Shaggy for golfing off one byte with includes
Thanks @Neil for golfing off two bytes

**Code separated into individual functions 92 bytes**

```
f=(x,a=[])=>a.includes(x)?a:f(k(x),a,a.push(x))
p=y=>y?y*p(y-1):1
k=n=>n?p(n%10)+k(n/10|0):0

```

**Code on one line 92 bytes**

```
f=(x,a=[])=>a.includes(x)?a:f((k=n=>n?(p=y=>y?y*p(y-1):1)(n%10)+k(n/10|0):0)(x),a,a.push(x))

```

## Explanation

Initially call the function with just a single argument, therefore a=\[\].

If x exists in the array a return a `a.includes(x)?a:...`

Otherwise, append x to a and pass the factorial digit sum and a to the function `(a.push(x),f(k(x),a))`

```
p=y=>y?y*p(y-1):1
k=n=>n?p(n%10)+k(n/10|0):0

```

Factorial Digit sum performed so that it will not exceed the maximum recursion limit.

**List of all possible endpoints:** 1, 2, 145, 169, 871, 872, 1454, 40585, 45361, 45362, 363601

Try it online!
> 4 votes

# Answer
# Haskell, ~~80~~ 67 bytes

```
g#n|elem n g=g|h<-g++[n]=h#sum[product[1..read[d]]|d<-show n]
([]#)

```

Try it online! Usage: `([]#) 132`

Edit: Saved 13 bytes with typs from Ørjan Johansen!
> 4 votes

# Answer
# Pyth, 9 bytes

```
.us.!MjNT
.us.!MjNTQ  implicit Q

.u          explained below
       N      current value
      j T     convert to decimal (list of digits)
   .!M        factorial of each digit
  s           sum

```

Try it online!

This answer uses `.u` ("Cumulative fixed-point. Apply until a result that has occurred before is found. Return all intermediate results.")
> 4 votes

# Answer
# Pyth, 30 bytes

```
W!hxYQQ=+YQKQ=Q0WK=+Q.!%KT=/KT

```

Try It Here
> 3 votes

# Answer
# Python 3, 110 bytes

```
g=lambda x:x<1or x*g(x-1)
def f(n):
 a=[];b=n
 while b not in a:a+=[b];yield b;b=sum(g(int(x))for x in str(b))

```

Try it online!
> 2 votes

# Answer
# R, 120 Bytes

```
o=scan()
repeat {
q=sum(factorial(as.double(el(strsplit(as.character(o[length(o)]), "")))))
if(q%in%o)break
o=c(o,q)
}
o

```
> 2 votes

# Answer
# Java 9 JSHell, 213 bytes

```
n->{Set<Integer>s=new HashSet<>();
return IntStream.iterate(n,i->(""+i).chars()
.map(x->x<50?1:IntStream.rangeClosed(2,x-48)
.reduce(1,(a,b)->a*b)).sum()).boxed()
.takeWhile(x->s.add(x)).collect(Collectors.toList());}

```

Try it online!

Note: This solution relies on the string representation of a number having code points in the range 48-57. Works for ASCII, UTF-8, Latin-1, all ISO-8859-\* character sets, most code pages. Does not work for EBCDIC. I don't think anyone will deduct points for that. :)

Ungolfed:

```
Function<Integer, List<Integer>> f =        // function from Integer to List of Integer
n -> {
    Set<Integer> s = new HashSet<>();       // memo of values we've seen
    return IntStream.iterate(n,             // iterate over n, f(n), f(f(n)), etc.
    i -> (""+i).chars()                     // the sumFac function; for all chars
        .map(x -> x < 50? 1 :               // give 1 for 0! or 1!
        IntStream.rangeClosed(2, x-48)      // else produce range 2..d
        .reduce(1,(a,b)->a*b))              // reduction to get the factorial
        .sum())                             // and sum up the factorii!

                                            // now we have a stream of ints
                                            // from applying sumFac repeatedly
        .boxed()                            // box them into Integers (thanks, Java)
        .takeWhile(x->s.add(x))             // and take them while not in the memo
        .collect(Collectors.toList());      // collect them into a list
}

```

Notes:

* The return value of Set::add is very helpful here; returns true **iff** the item was not in the set
* I was being sarcastic when I said "Thanks, Java"
* *factorii* isn't really a word; I just made that up
> 2 votes

# Answer
# Pyth, ~~22~~ 11 bytes

```
.usm.!sd+Nk

```

Try it online!

Lots of credit to Leaky Nun's answer, which introduced me to `.u`, and helped save a massive 11 bytes of this program.

Explanation:

```
.usm.!sd+NkQ | ending Q is implicitly added
             | Implicit: Q = eval(input())
.u         Q | Repeat the function with initial value Q until a previous value is found. Return all intermediate values
  s          | Summation
   m.!sd     | For each character 'd' in the string, convert to integer and take the factorial
        +Nk  | Convert function argument to string

```
> 2 votes

# Answer
# Husk, 6 bytes

```
U¡oṁΠd

```

Try it online!
> 2 votes

# Answer
# Axiom, 231 bytes

```
l(a:NNI):List NNI==(r:List NNI:=[];repeat(r:=cons(a rem 10,r);a:=a quo 10;a=0=>break);r)
g(a:NNI):NNI==reduce(+,[factorial(x) for x in l(a)])
h(a:NNI):List NNI==(r:=[a];repeat(a:=g(a);member?(a,r)=>break;r:=cons(a,r));reverse(r))

```

not golfed functions and some test

```
-- convert one NNI in its list of digits
listify(a:NNI):List NNI==
    r:List NNI:=[]
    repeat
        r:=cons(a rem 10,r)
        a:=     a quo 10
        a=0=>break
    r

-- g(1234)=1!+2!+3!+4!
SumfactorialDigits(a:NNI):NNI==reduce(+,[factorial(x) for x in listify(a)])

ListGenerateFromSumFactorialDigits(a:NNI):List NNI==
    r:=[a]
    repeat
       a:=SumfactorialDigits(a)
       member?(a,r)=>break
       r:=cons(a,r)
    reverse(r)

(9) -> h 132
   (9)
   [132, 9, 362880, 81369, 403927, 367953, 368772, 51128, 40444, 97, 367920,
    368649, 404670, 5810, 40442, 75, 5160, 842, 40346, 775, 10200, 6, 720,
    5043, 151, 122, 5, 120, 4, 24, 26, 722, 5044, 169, 363601, 1454]

```
> 1 votes

# Answer
## C, 161 bytes

```
f(a){return a?a*f(a-1):1;}
a(l){return l?f(l%10)+a(l/10):0;}
c,t,o;r(i){for(t=o=i;t=a(t),o=a(a(o)),c=t^o;);for(t=i;t^c;printf("%d ",t),c=c|t^o?c:o,t=a(t),o=a(o));}

```

See it work online.
> 1 votes

# Answer
# TI-BASIC, ~~85~~ ~~79~~ ~~64~~ 60 bytes

```
:Prompt L₁                             //Get input as 1 length list, 4 bytes
:Lbl C                                //create marker for looping, see below, 3 bytes
:int(10fPart(Xseq(10^(~A-1),A,0,log(X //split input into list of digits, 20 bytes
:sum(Ans!→X                           //factorial and sum the list, write to new input, 6 bytes
:If prod(L₁-X                         //Test to see if new element is repeated, see below, 7 bytes
:Then                                 //Part of If statement, 2 bytes
:augment(L₁,{X→L₁                     //Push new input to List 1, 10 bytes
:Goto C                               //Loop back to beginning, 3 bytes
:Else                                 //Part of If statement, 2 bytes
:L₁                                   //Print Answer, 2 bytes

```

Since this is running on a graphing calculator, there is limited RAM. Try testing it with numbers that loop quickly, like `169`.

**More Explanation:**

```
:int(10fPart(Xseq(10^(~A-1),A,0,log(X
              seq(10^(~A-1),A,0,log(X //Get a list of powers of 10 for each digit (i.e. 1, 0.1, 0.01, etc.)
             X                        //Multiply by input
       fPart(                         //Remove everything but the decimal
     10                               //Multiply by 10 (move one digit in front of the decimal
:int(                                 //Truncate to an integer

```

`If prod(L₁-X` works by subtracting the new element from the old list, then multiplying all the elements of the list together. If the element was already in the list, the product will be `0`, a falsey value. Otherwise, the product will be a positive integer, a truthy value.
> 1 votes

# Answer
# Java 7, 220 bytes

```
String c(int n){String r=n+",",c;for(;!r.matches("^"+(c=(n=d(n))+",")+".*|.*,"+c+".*");r+=c);return r;}int d(int n){int s=0;for(String i:(n+"").split(""))s+=f(new Long(i));return s;}long f(long x){return x<2?1:x*f(x-1);}

```

**Explanation:**

```
String c(int n){                            // Method with integer parameter and String return-type
  String r=n+",",                           //  Result-String (which starts with the input integer + a comma
         c;                                 //  Temp String
  for(;!r.matches(                          //  Loop as long as the result-String doesn't match the following regex:
    "^"+(c=(n=d(n))+",")+".*|.*,"+c+".*");  //    "^i,.*|.*,i,.*" where `i` is the current integer
                                            //   `n=d(n)` calculates the next integer in line
                                            //   `c=(n=d(n))+","` sets the temp String to this integer + a comma
    r+=c                                    //   And append the result-String with this temp String
  );                                        //  End of loop
  return r;                                 //  Return the result-String
}                                           // End of method

int d(int n){                               // Separate method (1) with integer parameter and integer return-type
  int s=0;                                  //  Sum
  for(String i:(n+"").split(""))            //  Loop over the digits of `n`
    s+=f(new Long(i));                      //   And add the factorial of these digits to the sum
                                            //  End of loop (implicit / single-line body)
  return s;                                 //  Return the sum
}                                           // End of separate method (1)

long f(long x){                             // Separate method (2) with long parameter and long return-type (calculates the factorial)
                                            // (NOTE: 2x `long` and the `new Long(i)` is shorter than 2x `int` and `new Integer(i)`, hence long instead of int)
  return x<2?                               //  If `x` is 1:
      1                                     //   return 1
    :                                       //  Else:
      x*f(x-1);                             //   return `x` multiplied by the recursive-call of `x-1`
}                                           // End of method (2)

```

**Test code:**

Try it here.

```
class M{
  String c(int n){String r=n+",",c;for(;!r.matches("^"+(c=(n=d(n))+",")+".*|.*,"+c+".*");r+=c);return r;}int d(int n){int s=0;for(String i:(n+"").split(""))s+=f(new Long(i));return s;}long f(long x){return x<2?1:x*f(x-1);}

  public static void main(String[] a){
    System.out.println(new M().c(132));
  }
}

```

**Output:**

```
132,9,362880,81369,403927,367953,368772,51128,40444,97,367920,368649,404670,5810,40442,75,5160,842,40346,775,10200,6,720,5043,151,122,5,120,4,24,26,722,5044,169,363601,1454,

```
> 1 votes

# Answer
# GolfScript, 44 bytes

```
~]{..)\;10base{,1\{)*}/}%{+}*.@\+@@?)!}do);`

~                                             eval input
 ]                                            initialization
  {                                   }do     do...
   ..)\;                                          initialization
        10base                                    get digits
              {,1\{)*}/}%                         factorial each
                         {+}*                     sum
                             .@\+@@?)!        while result not found
                                         );   drop last element
                                           `  tostring

```

Try it online!

The factorial part is from here.
> 1 votes

# Answer
# , 40 31 bytes

Edit: 9 bytes saved using the improvements by FrownyFrog. Thanks!

```
f=.$:@,~`]@.e.~[:+/@:!10#.inv{:

```

Original code:

```
f=.[`($:@,)@.([:-.e.~)[:+/!@("."0&":@{:)

```

In this case I decided to count the bytes for the verb definition, since otherwise it doesn't work in the interpreter.

Explanation:

```

                         (        {:) - Takes the last element of the array
                               ":@    - converts it to string
                          "."0&       - converts each character back to integer
                       !@             - finds the factorials
                     +/               - sums them
                   [:                 - cap (there are 2 derived verbs above, we need 3 for a fork)
          (    e.~)                   - check if the result is present in the list
             -.                       - negates the above check
           [:                         - cap
        @.                            - Agenda conjunction, needed for the recursion
  ($:@,)                              - if the result is not in the list, add it to the list and recur
[`                                    - if the result is in the list, display it and stop

```

Try it online!
> 1 votes

# Answer
# Tcl, 143 bytes

```
proc P {n L\ ""} {proc F n {expr $n?($n)*\[F $n-1]:1}
while {[set n [expr [join [lmap d [split $n ""] {F $d}] +]]] ni $L} {lappend L $n}
set L}

```

Try it online!
> 1 votes

# Answer
# APL (Dyalog Extended), ~~17~~ ~~16~~ 15 bytes

Saved 1 byte thanks to @Adám and another later

```
f←(#+.(!⍎)⍕)⌂traj

```

Try it online!

`traj` is a function in the dfns workspace that runs a function until a cycle is detected. Here, that function is `#+.(!⍎)⍕`.  turns the argument into a string. Each character/digit (`¨`) is executed/turned into a number (). `!` finds the factorial of each of these digits. Then `+` adds up all these factorials. `#` is used because `#⍎foo` just executes `foo`, so it's `#f.⍎` is practically the same as `{f/⍎¨⍵}` here.

# APL (Dyalog Unicode), ~~25~~ 20 bytes

Saved 5 bytes thanks to @Adám!

```
1↓{⍵,⍨+/!⍎¨⍕⊃⍵}⍣(⊃∊)

```

Try it online!

Output is reversed.

This is very similar to the code above, but uses the power operator () to run the dfn until a cycle is reached, then drops the first element (`1↓`) because it runs 1 extra time. `{⍵,⍨+/!⍎¨⍕⊃⍵}` applies the function in the question to the first element of the argument (`⊃⍵`), then prepends it to the argument (`⍵,⍨`). Each time it is called, the list grows by one. The train `⊃∊` is applied with the next result on the left side and the previous result on the right side and tells ⍣ when to stop.  is membership and tells which of the next result's elements are in the previous results (if one of them is repeated, there is a cycle). Then it picks the first of these booleans () because we need a single value and the rest have been checked already in previous iterations.
> 1 votes

# Answer
# PowerShell Core, 87 bytes

```
param($r)for(;$r-notin$l){$l+=,$r
$r=("$r"|% t*y|%{1.."$_"-ne0-join'*'})-join'+'|iex}$l

```

Try it online!

Thanks to mazzy for saving a lot of bytes!

## Explained (old implementation, but close enough)

```
param($r)for(;$r-notin$l                       # Checks that the last computed value isn't an existing one
                        ){$l+=,$r              # Adds it to the list

$r=("$r"|                                      # Converts r as a string
      % t*y|                                   # Converts it to a char array
      %{1.."$_"-ne0-join'*'}                   # Builds the factorial calculation strings and handles 0!. e.g. 1*2*3*4
   )-join'+'|iex}                              # Joins them with "+" and computes it. e.g. 1*2*3*4+1*2*3

$l                                             # Returns all the values in the list

```
> 1 votes

# Answer
# Perl 5 `-MList::Util=product,sum -n`, 49 bytes

```
say&&($_=sum map{product 1..$_}/./g)until$k{$_}++

```

Try it online!
> 0 votes

# Answer
# Wolfram Language (Mathematica), 72 bytes

```
Most@NestWhileList[Total[IntegerDigits@#!]&,#,DuplicateFreeQ@*List,All]&

```

Try it online!

Keeps applying `sumFac` to it's own output until it sees a duplicate value, then returns a list of all values excluding that final duplicate.
> 0 votes

# Answer
# Stax, 10 bytes

```
│¼µ\Ä▬Éε╩X

```

Run and debug it
> 0 votes

# Answer
# Perl 5 `-n`, 65 bytes

```
say,(map{$f=1;map{$f*=$_}2..$_;$.+=$f}/./g),$_=$.until$.=$r{$_}++

```

Try it online!

Uses `map` as regular loops (ignoring return value), and `$.` as a temporary variable (to save space before `until`).
> 0 votes

---
Tags: code-golf, math, number, sequence, factorial
---


title: Topple some dominoes!

text:
# Question
Title: Topple some dominoes!
> Thanks to this question for some inspiration

In this challenge we will represent a line of dominoes as a string of `|`, `/` and `\`. You will be given a string of dominoes as input and you must determine what they look like when they have settled. Here are the rules for how dominoes fall over

* A standing domino, `|`, left of a left fallen domino, `\`, will become a left fallen domino as well.
* A standing domino, `|`, right of a right fallen domino, `/`, will become a right fallen domino as well.
* If a standing domino is between a left fallen `\` and a right fallen `/` domino, it will remain standing.

These rules are applied repeatedly until the arrangement no longer changes.

Here is an example of how a single input might arrive at its conclusion

```
|||||||\/|||||||\||\|||/||||||\|||||

||||||\\//|||||\\|\\|||//||||\\|||||
|||||\\\///|||\\\\\\|||///||\\\|||||
||||\\\\////|\\\\\\\|||////\\\\|||||
|||\\\\\////|\\\\\\\|||////\\\\|||||
||\\\\\\////|\\\\\\\|||////\\\\|||||
|\\\\\\\////|\\\\\\\|||////\\\\|||||

\\\\\\\\////|\\\\\\\|||////\\\\|||||

```

Your task is to write code that finds and outputs the end result of a input. You may assume that the input is always valid and contains at least 2 characters.

This is so answers will be scored in bytes with fewer bytes being better.

## Test cases

```
|||/||||  -> |||/////
|||\||||  -> \\\\||||
|/||||\|  -> |///\\\|
||/|||\|  -> ||//|\\|
||\|||/|  -> \\\|||//

```

# Answer
> 13 votes
## Retina, 32 bytes

```
+`(/.\\)|(/)\||\|(\\)
$1$2$2$3$3

```

Try it online!

### Explanation

The `+` tells Retina to run the replacement in a loop until it fails to change the string. Each replacement computes one step the falling dominoes. The replacement itself is really three replacements in one, but this ensures that they happen simultaneously:

```
(/.\\)...
$1

```

This just matches `/|\` (as well as `/\\` and `/\\`, but those don't matter) and reinserts it unchanged. The purpose of this is to skip over `|` with fallen dominoes on both sides, because this is shorter than ruling out those cases with separate lookarounds in the other two cases.

```
...(/)\|...
$2$2

```

This matches `/|` and turns it into `//`.

```
...\|(\\)
$3$3

```

This matches `|\` and turns it into `\\`.

# Answer
> 5 votes
# Python 2, ~~115~~ ~~114~~ ~~111~~ ~~108~~ ~~98~~ 95 bytes

<sup>-1 byte thanks to ovs</sup>

```
a=input()
for i in range(4)*len(a):a=a.replace('//|x||\ \\'[i::4],'/\/x|\/ \\'[3-i::4])
print a

```

Try it online!

# Answer
> 4 votes
# , 23 bytes

```
òÓ¯À<!|¨Ü©ü¨¯©|ÜÀ!/±±²²

```

Try it online!

Really, this is very similar to the retina answer, just that it looks uglier. Uses regex compression.

Hexdump:

```
00000000: f2d3 afc0 3c21 7ca8 dca9 fca8 afa9 7cdc  ....<!|.......|.
00000010: c021 2fb1 b1b2 b2                        .!/....

```

Explanation:

`ò` tells V to run until the string doesn't change. The rest is a compressed regex. Let's convert it into the vim equivalent...

```
:s/\v\/@<!\|(\\)|(\/)\|\\@!/\1\1\2\2/g

:s/                                     " Substitute...
   \v                                   " Turn on magic (use less escaping)
          \|                            " A bar
            (\\)                        " Followed by a captured backslash
       @<!                              " That is not preceded by
     \/                                 " A forward slash
                |                       " OR...
                 (\/)                   " A captured forward slash
                     \|                 " Followed by a bar
                       \\@!             " That is not followed by a backslash
                           /            " Replace this with
                            \1\1        " Pattern 1 twice (will be empty if we matched the second path)
                                \2\2    " Pattern 2 twice (will be empty if we matched the first path)
                                    /g  " Replace every match on this line

```

# Answer
> 4 votes
# SNOBOL4 (CSNOBOL4), ~~117~~ ~~115~~ ~~112~~ 111 bytes

```
	D =INPUT
S	D '/|\' ='_'	:S(S)
	E =D
	D '/|' ='//'
	D '|\' ='\\'
	D E	:F(S)
R	D '_' ='/|\'	:S(R)
	OUTPUT =D
END

```

Try it online!

Credit to Rod's python answer for the idea for the stopping condition with a second variable to see changes rather than testing `D '/|' | '|\'`.

```
	D =INPUT		;* read input
S	D '/|\' ='_'	:S(S)	;* replace '/|\' with '_', recursively
	E =D			;* set E to D, this is the while loop
	D '/|' ='//'		;* topple right
	D '|\' ='\\'		;* topple left
	D E	:F(S)		;* if D doesn't match E, goto S
R	D '_' ='/|\'	:S(R)	;* replace '_' with '/|\' (inverse of statement S)
	OUTPUT =D		;* output
END

```

# Answer
> 3 votes
# Perl 5, 39 + 1 (`-p`) = 40 bytes

```
s%(?<!/)\|(\\)|(/)\|(?!\\)%$+$+%g&&redo

```

Try it online!

# Answer
> 3 votes
# Haskell, ~~114~~ 107 bytes

```
until=<<((==)=<<)$g
g s=t<$>zip3('|':s)s(tail s++"|")
t(l,'|',r)|l<'0',r/='\\'=l|r=='\\',l>'/'=r
t(_,e,_)=e

```

Try it online! The first line defines an anonymous function.

### Explanation:

* `until=<<((==)=<<)$g` is a fix point function (see here for an explanation) which applies the function `g` to the input string until the result no longer changes.
* `zip3('|':s)s(tail s++"|")` creates for each domino, that is character in the string `s`, a triple with the pre- and succeeding domino, padding with `|` at the edges. E.g. `/\|` becomes `[(|,/,\),(/,\,|),(\,|,|)]` (ignoring escaping).
* Then the function `t` is applied to each of the triples to compute the new position of the centre piece of the triple.

# Answer
> 3 votes
# Prolog (SWI), 132 bytes

```
+[]-->[].
+[47,124,92|T]-->"/|\\",+T.
+[47,47|T]-->"/|",+T.
+[92,92|T]-->"|\\",+T.
+[X|T]-->[X],+T.
X+Y:- +(N,X,[]),!,(X=N,Y=N;N+Y).

```

Try it online!

This program defines a predicate `+/2` that is true if the second argument is the settled version of the first. Both arguments are lists of character codes.

## Explanation

This solution uses a DCG to figure out what the next step is and then repeatedly calculates the next step until the next step is the same as the current step.

### The DCG

```
+[]-->[].
+[47,124,92|T]-->"/|\\",+T.
+[47,47|T]-->"/|",+T.
+[92,92|T]-->"|\\",+T.
+[X|T]-->[X],+T.

```

These five lines of code define a DCG (Definite Clause Grammar) rule `+` that is used in the program to calculate a single step of dominoes toppling. DCGs in Prolog work by finding the first case of the rule whose right hand side matches the string and determining the argument of the rule on the left hand side through that process. If a case fails to match then it will backtrack and try a later case.

```
+[]-->[].

```

This line represents the base case of the `+` rule. It simply states that if there are no dominoes currently then in the next step there will still be no dominoes.

```
+[47,124,92|T]-->"/|\\",+T.

```

Since this program deals exclusively with lists of character codes it is important to note that the character codes for `/`, `\`, and `|` are 47, 92, and 124 respectively. This case of the `+` rule handles the `/|\` string.

```
+[47,47|T]-->"/|",+T.

```

This case handles a right falling domino knocking over the domino the right of it. Since it comes after the case for handling `/|\` it will not be used for that possibility.

```
+[92,92|T]-->"|\\",+T.

```

Handles the case for a left falling domino knocking over the domino to the left of it.

```
+[X|T]-->[X],+T.

```

This is the wildcard case. Since nothing else changes besides what is described above, so long as there is text left in the input string it will just copy it over to the output so long as it does not match any of the above cases.

### The Predicate

```
X+Y:- +(N,X,[]),!,(X=N,Y=N;N+Y).

```

The main predicate takes two arguments, the first one is the initial domino setup, the second is the settled dominoes. Since this is Prolog the second can be undetermined and the program will calculate it. The predicate in and of itself is fairly simple `+(N,X,[])` calls the DCG and calculates the next step of the dominoes storing it in `N`. `(X=N,Y=N;N+Y)` checks if the next step of the dominoes is the same as the current and if it is it sets `Y` to it since the dominoes must have settled and if it is not it recurses, calling the same predicate with the next step of the dominoes `N` instead of `X`.

# Answer
> 1 votes
# APL (Dyalog), 36 bytes

```
({(↑∘1¨3 ¯3)⍳⊂⍵≠'/|\'}⊃'\/',2⊃⊢)⌺3⍣≡

```

Try it online!

-3 partially thanks to Cows Quack.

Feels so ungolfed...:(

# Answer
> 1 votes
# Perl 5, 52+1(-p) = 53 bytes

*-6 bytes thanks to mik*

Probably not the best possible for Perl, but it's what I could come up with.

```
0while(s/(?<!\/)\|(?=(\\))|(?<=(\/))\|(?!\\)/$1$2/g)

```

### Explanation

```
while(
  s/
    (?<!\/)\|(?=(//)) # If there's a | that precedes a \ but doesn't follow a /, capture /
      | # Or
    (?<=(\/))\|(?!//)/ # If there's a | that follows a / doesn't precede a \, capture /
  /$1$2/ # Replace all | with capture group 1 or 2, as one of the two will always be empty
  g # Repeat as much as possible for this string
)

```

Try it online!

# Answer
> 1 votes
# Perl 5 `-p`, 44 bytes

```
1while s,(/)\|(?!\\)|(?<!/)\|(\\),$1$1$2$2,g

```

Try it online!

### Explanation

```
1while s,                        ,        ,g   while anything found substitute globally
         (/)\|(?!\\)              $1$1         /| that is not followed by \ to //
                    |                          or
                     (?<!/)\|(\\)     $2$2     |\ that is not preceded by / to \\

```

# Answer
> 1 votes
## face, 166 bytes

```
\|/,cm_/o>AvI[IIcP/+PP|m_/m*/Sl*Im1/11:~-_I|'|?_1-_P|?_1`I-III_|+II|'I.C:1-_I|?_C'|-_P|?_C_|'I-_I|`I?_!'I.C:!'|'|-III+II|'I:C_|-PPP+PPI'I?I~_I-PPP+PP|-**1?*~Sl*Iw*I*>

```

Takes input as a command line argument and outputs to STDOUT. This only works in commit 86494f6 and beyond due to a bugfix in that commit.

Wrapped for aesthetics:

```
\|/,cm_/o>AvI[IIcP/+PP|m_/m*/Sl*Im1/11:~-_I|'|?_1-_P|?_1`I
-III_|+II|'I.C:1-_I|?_C'|-_P|?_C_|'I-_I|`I?_!'I.C:!'|'|-III
+II|'I:C_|-PPP+PPI'I?I~_I-PPP+PP|-**1?*~Sl*Iw*I*>

```

And ungolfed / commented:

```
\|/,cm_/o>              ( setup )

AvI[II                  ( store input into I )
cP/+PP|m_/              ( store 92, ascii for \, into P, meaning prev char )
m*/Sl*Im1/11            ( store length of input into counter variable * )

( main loop: )
:~

    -_I|'|?_1           ( branch to 1 if the character is not \ )
    -_P|?_1             ( also branch to 1 if the previous character wasn't | )
    `I-III_|+II|'I      ( we have a sequence |\ so prev needs to be toppled )
    .C                  ( jump to C, the "continue" label at end of loop )

    :1
    -_I|?_C             ( branch to C if the character is not | )
    '|-_P|?_C           ( also branch to C if the previous character wasn't / )
    _|'I-_I|`I?_!       ( branch to ! if the next character isn't \ )
    'I.C:!              ( otherwise, skip the next \ and branch to continue )
    '|'|-III+II|'I      ( if all conditions hold we have /|| or /|/ so topple )

    :C
    _|                  ( reset pointer to source )
    -PPP+PPI            ( update prev variable )
    'I                  ( step through data )

?I~

_I-PPP+PP|-**1          ( reset input/prev and decrement counter )
?*~                     ( repeat main loop as many times as there are chars )

Sl*Iw*I*>               ( output final string to stdout )

```

There's a few subtle tricks in here that shave off a few extra bytes, such as

* the naming of the variables | and /, whose ASCII values are accessed via introspection later in the code
* the `'|` on the first line of the main loop, which is called there instead of on the second line in order to set the | pointer for use in the second section of the main loop

# Answer
> 1 votes
# Clean, 98 bytes

```
import StdEnv
$['/|':t]=['//': $t]
$['|\\':t]=['\\\\': $t]
$[h:t]=[h: $t]
$e=e
f=until(\e=e== $e)$

```

Try it online!

# Answer
> 1 votes
# Jelly, 32 bytes

```
i@€Ø2jḅ3ị“½jỊA!S’ḃ3¤Ɗ3ƤƊÐLịɗ“\|/

```

Try it online!

There's probably a much better way to do this.

# Answer
> 0 votes
# Ruby, 83 bytes

Technically cheatable with `9.times`, or even just `999.times` but I don't feel like being cheap :)

Still has huge golfing potential. (Note: `y while undone` is far longer than `x.size.times`)

```
->x{x.size.times{x.gsub! /\/\|\\?|\|\\/,'/|\\'=>'/|\\','/|'=>'//','|\\'=>'\\\\'}
x}

```

Try it online!

# Answer
> 0 votes
# , 114 bytes

```
function(d){g=gsub
for(i in 1:nchar(d))d=g("/|","//",g("|\\","\\\\",g("/|\\","_",d,f=T),f=T),f=T)
g("_","/|\\",d)}

```

Try it online!

Returns an escaped string.

# Answer
> 0 votes
# C (gcc), 183 bytes

```
D,i;f(char*S){char*s=malloc(-~strlen(S));for(D=1;D--;strcpy(S,s))for(strcpy(s,S),i=0;s[i];i++)s[i]>92&&(S[-~i]==92&&S[~-i]!=47&&(s[i]=92,D=1)||S[~-i]==47&&S[-~i]!=92&&(s[i]=47,D=1));}

```

Try it online!

---
Tags: code-golf, string, dominoes
---


title: The Unholy numbers

text:
# Question
Title: The Unholy numbers
This challenged is highly inspired by what @Mego created with his Holy and Holier numbers, lots of thanks to him and his puns.

Holy numbers are numbers composed of only the digits with *holes*, which are:

```
04689

```

Numbers with at least one unholy digit are considered unholy. Unholy digits are evil by definition, but being close to holy digits help them become neutral. Hence, the closer they are, the less unholy (1 when adjacent).

The unholiness of a number is the sum of the unholyness of its digits, a number composed of only unholy number has an infinite unholiness.

```
Number            :8 5 5 8 7
Digital Unholiness:0+1+1+0+1
Total Unholiness  :3

Number            :0 1 7 5 5 2 8 5 7
Digital Unholiness:0+1+2+3+2+1+0+1+2
Total Unholiness  :12

Number            :1 5 7 3 2 1
Digital Unholiness:∞+∞+∞+∞+∞+∞
Total Unholiness  :∞

Number            :0 4 6 8 9
Digital Unholiness:0+0+0+0+0
Total Unholiness  :0

```

### Your task

You have to write a program or function that takes a positive integer or a string only composed of digits as input, and output its unholiness. If you chose to use an integer as input, you can assume it will never have a leading `0` as your language may drop it.

In case of infinite unholiness, you can chose between three outputs

* The character  (3 bytes)
* Infinite output containing at least 1 non-zero digit, but only digits.
* A built-in `Infinity` value.

This is code-golf, so the shortest code in byte wins, good luck!

# Answer
> 3 votes
# MATL, ~~25~~ 24 bytes

```
7Zq1hVmt~f!wf-|X<st~?xYY

```

**Try it online!**

Input is a string. In the output, infinity is natively displayed as `Inf`.

### Explanation

```
7         % number literal
Zq        % prime numbers up to a 7: [2 3 5 7]
1         % number literal
h         % horizontal concatenation
V         % convert numbers to string: '2  3  5  7  1'
m         % take input implicitly. Determine which digits are 1,2,3,5,7
t         % duplicate
~         % element-wise negate: which digits are 4,6,8,9,0
f         % indices of occurrences of digits 4,6,8,9,0
!         % transpose into column array
w         % swap elements in stack
f         % indices of occurrences of digits 1,2,3,5,7
-         % element-wise subtraction with broadcast. Gives 2D array
|         % element-wise absolute value
X<        % minimum of each column
s         % sum of elements of array
t         % duplicate
~         % element-wise negate
?         % if all elements are true
  x       %   delete
  YY      %   push infinity
          % (implicit) end if
          % (implicit) convert to string and display

```

# Answer
> 5 votes
# GNU APL, 27 bytes

```
{+/⌊/|(⍳⍴⍵)∘.-(⍵⍳⍕⍟788)~⍴⍵}

```

Try it online!

To try it out using the above link, IO must be set to 0 and the input is provided as a string. For example:

```
⎕IO←0
{+/⌊/|(⍳⍴⍵)∘.-(⍵⍳⍕⍟788)~⍴⍵}'017552857'

```

## Explanation

```
{+/⌊/|(⍳⍴⍵)∘.-(⍵⍳⍕⍟788)~⍴⍵}  ⍝ Note: below explanation uses as example input 017552857
{                            ⍝ dfn
                  ⍟788       ⍝ computes natural log of 788, which happens to be 6.66949809, containing only (and all) holy digits
                 ⍕           ⍝ Converts this number to a string
               ⍵⍳            ⍝ Finds the indexes of chars in the right argument ⍵ which are present in the computed decimal. Items not found map to the length of the list, e.g. '017552857'⍳'6.66949809' -> 9 9 9 9 9 9 9 6 0 9
                      ~⍴⍵    ⍝ Removed all non-found indexes from the list 9 9 9 9 9 9 9 6 0 9 -> 6 0
      (⍳⍴⍵)                  ⍝ List of ascending integers up the length of the argument ⍵: 0 1 2 3 4 5 6 7 8
           ∘.-               ⍝ Inner product of the ascending integers 0..8 minus the match indexes 6 0. Result is ¯6 0, ¯5 1, .., 2 8
     |                       ⍝ Absolute value of all elements
   ⌊/                        ⍝ Take the minimum of each pair to get the closest distance to a Holy number 0 1 2 3 2 1 0 1 2
 +/                          ⍝ Sum this list

```

The reason for choosing GNU APL is that handily it will return the internal representation of infinity, '∞', when calculating the minimum value of the empty list. Summing this still retains ∞, which is then returned.

`⍟788` was a cheeky way to lose a byte. I ended up writing a program to brute force inputs to functions until I found a suitable result which contained only holy numbers. Brute force program below:

```
    (,(⍳99)∘.{∧/(~'12357'∊c),'04689'∊(c←⍕b←⍺÷⍵):(⍺,'f',⍵,'=',b,'|') ⋄ 0}⍳99)~0

```

In this case it sees if any values of `⍺÷⍵` in `0 < ⍺,⍵ < 100` meet the condition. I manually played around with the functions to test.

It's a bit of a shame that this challenge doesn't allow undefined behaviour for the infinity case or that Dyalog doesn't return an infinite data type instead of throwing an error, otherwise the following solution would work in Dyalog APL:

# APL (Dyalog Unicode), 23 bytes

```
{+/⌊/|(⍳⍴⍵)∘.-⍸⍵∊⍕⍟788}

```

Try it online!

# Answer
> 4 votes
## Python (3), ~~137~~ 131 bytes

```
def f(s):
 l=range(len(s))
 r=[min(i)for i in zip(*[[abs(j-i)for j in l]for i in l if s[i]in'46890'])]
 return sum(r)if r else'∞'

```

## Results

```
>>> [f(i) for i in ['85587', '012321857', '157321', '04689']]
[3, 12, '∞', 0]

```

# Answer
> 4 votes
# Ruby (2.7+), ~~69~~ 63 chars, ~~71~~ 65 bytes

```
->n{x=!r=l=0;n.map{'04689'[_1]?x=l=0*r-=l*l/4:r+=l+=1};x ?r:?∞}

```

Unsupported by TIO

# Ruby (other), ~~71~~ 65 chars, ~~73~~ 67 bytes

```
->n{x=!r=l=0;n.map{|c|'04689'[c]?x=l=0*r-=l*l/4:r+=l+=1};x ?r:?∞}

```

Try it online!

## How it works:

* Iterate through the digits
* If a digit is holy
* reset increment
* subtract a number\* from the score to correct the overcounting
* If a digit is unholy
* add 1 to increment
* add increment to score

\*turns out this number depends only on the current value of the increment (`l` in the code), it's OEIS A002620 (quarter squares) (`l*l/4` in the code).

Returns the  character in case of infinity.

Interesting trick: `x=l=0*r-=l*l/4` is equivalent to `(r-=l*l/4;x=l=0)` but using `*` instead of `;` makes it a single statement allowing `()` to be dropped.

Edit: changed input type, now takes a list of characters.

# Answer
> 3 votes
# Pyth, ~~31~~ ~~29~~ ~~27~~ 25 bytes

```
smhS.e?}b"04689"akd.n4zUz

```

Try it online: Demonstration or Test Suite

For each digit I compute the distances to each number. A distance is infinty, if the second digit is not holy. From these lists I take the minimal distance and sum it up.

### Explanation:

```
smhS.e?}b"04689"akd.n4zUz  implicit: z = input string of numbers
 m                     Uz  map each d in [0, 1, ..., len(z)-1] to:
    .e                z      map each k (index), b (value) of b to:
                akd            absolute difference between k and d

      ?}b"04689"               if b in "04689" else
                   .n4         infinity
   S                           sort
  h                            take the first element (=minimum)
s                              print the sum

```

# Answer
> 2 votes
## JavaScript (ES6), 93 bytes

```
s=>[...s].map(n=>/[12357]/.test(n)?++u:u=0,u=1/0).reverse().map(n=>r+=n?n<++u?n:u:u=0,r=0)&&r

```

If `Infinity` isn't a legal infinity, then add 13 bytes for `==1/0?'∞':r`.

# Answer
> 2 votes
# 05AB1E, 20 bytes

```
ŽāĀISåƶZĀiāδαø€ßOë'∞

```

Try it online or verify all test cases.

**Explanation:**

```
ŽāĀ                # Push compressed integer 40689
   IS              # Push the input-string, converted to a list of digits
                   #  i.e. "085281755283" → [0,8,5,2,8,1,7,5,5,2,8,3]
     å             # Check for each digit if it's in 40689 (1 if truthy; 0 if falsey)
                   #  → [1,1,0,0,1,0,0,0,0,0,1,0]
      ƶ            # Multiply each value by its 1-based index
                   #  → [1,2,0,0,5,0,0,0,0,0,11,0]
       Z           # Push the maximum of this list (without popping)
                   #  → 11
        Āi         # If this maximum is not 0 (so there are holy digits present):
                   #   → 1 (truthy)
          ā        #  Push a list in the range [1, list-length] (without popping the list)
                   #   → [1,2,3,4,5,6,7,8,9,10,11,12]
           δ       #  Apply double-vectorized:
            α      #   Take the absolute difference between each value
                   #    → [[0,1,2,3,4,5,6,7,8,9,10,11],[1,0,1,2,3,4,5,6,7,8,9,10],
                   #       [1,2,3,4,5,6,7,8,9,10,11,12],[1,2,3,4,5,6,7,8,9,10,11,12],
                   #       [4,3,2,1,0,1,2,3,4,5,6,7],[1,2,3,4,5,6,7,8,9,10,11,12],
                   #       [1,2,3,4,5,6,7,8,9,10,11,12],[1,2,3,4,5,6,7,8,9,10,11,12],
                   #       [1,2,3,4,5,6,7,8,9,10,11,12],[1,2,3,4,5,6,7,8,9,10,11,12],
                   #       [10,9,8,7,6,5,4,3,2,1,0,1],[1,2,3,4,5,6,7,8,9,10,11,12]]
             ø     #  Then zip/transpose the list of lists; swapping rows/columns
                   #   → [[0,1,1,1,4,1,1,1,1,1,10,1],[1,0,2,2,3,2,2,2,2,2,9,2],
                   #      [2,1,3,3,2,3,3,3,3,3,8,3],[3,2,4,4,1,4,4,4,4,4,7,4],
                   #      [4,3,5,5,0,5,5,5,5,5,6,5],[5,4,6,6,1,6,6,6,6,6,5,6],
                   #      [6,5,7,7,2,7,7,7,7,7,4,7],[7,6,8,8,3,8,8,8,8,8,3,8],
                   #      [8,7,9,9,4,9,9,9,9,9,2,9],[9,8,10,10,5,10,10,10,10,10,1,10],
                   #      [10,9,11,11,6,11,11,11,11,11,0,11],[11,10,12,12,7,12,12,12,12,12,1,12]]
              €ß   #  Get the minimum of each inner list
                   #   → [0,0,1,1,0,1,2,3,2,1,0,1]
                O  #  And sum everything together
                   #   → 12
         ë         # Else (no holy digits are present)
          '∞      '#  Push string "∞" instead
                   # (after which the top of the stack is output implicitly as result)

```

See this 05AB1E tip of mine (section *How to compress large integers?*) to understand why `ŽāĀ` is `40689`.

# Answer
> 2 votes
# Jelly, ~~18~~ 17 bytes

```
Dµ+ỊẒµ¬TạþTṂ€µ»İS

```

Try it online!

*-1 thanks to Jonathan Allan*

Did a lot of fiddling with compressed strings and `ȷ` literals before I realized that division by zero gives infinity. Takes input as an integer, since conversion to a digit list is one byte shorter (`D` versus `V€`)--and since half of the test cases have leading zeroes, which the spec also guarantees an integer-input solution never has to handle, here's the string version as well.

Jonathan Allan's golf cleverly avoids having to distinguish two different sources of zeroes by not finding the distances between holy digits and themselves.

```
Dµ                   Consider the decimal digits of the input.
  +Ị                 Increment 0s to 1s and 1s to 2s.
    Ẓ                For each digit, is it prime?
     µ               With this list of 0s for holy digits and 1s for holy digits,
        ạþ           table the absolute differences between
      ¬T             the indices of holy digits
          T          and the indices of unholy digits.
           Ṃ€        Take the minimum from each row,
                S    and sum
              »      the maxima of those minima and
             µ İ     their inverses.

```

# Answer
> 1 votes
# , 100 bytes

```
sum(sapply(0:(d=log10(n<-scan()))+1,function(x)min(abs(x-which(n%/%10^(0:d)%%10%in%c(0,4,6,8,9))))))

```

Try it online!

# Answer
> 1 votes
# Python 3, 96 bytes

```
lambda s:sum(min([9e999]+[abs(i-j)for j,c in enumerate(s)if c in'04689'])for i in range(len(s)))

```

Try it online!

# Answer
> 0 votes
# JavaScript (Node.js), 77 bytes

```
s=>s.reduce((m,c,i)=>m+Math.min(...s.map(c=>(i*i--)**.5+(174&1<<c?1/0:0))),0)

```

Try it online!

---
Tags: code-golf, number, sequence
---


# Question
Title: A083569: Smallest m not occurring earlier such that m+n is prime
Define a 1-indexed sequence as follows:

* `A083569(1) = 1`
* `A083569(n)` where `n` is an integer greater than `1`, is the smallest integer m not occurring earlier such that `m+n` is a prime number.

Your task is to take in `n` and return `A083569(n)`.

```
 n  A083569(n)
 1  1
 2  3
 3  2
 4  7
 5  6
 6  5
 7  4
 8  9
 9  8
10 13
11 12
12 11
13 10
14 15
15 14
16 21
17 20
18 19
19 18
20 17

```

More testcases can be found here. The original sequence on OEIS can be found here.

This is . Shortest answer in bytes wins. Standard loopholes apply.

# Answer
# Haskell, ~~87~~ ~~86~~ ~~83~~ ~~80~~ ~~74~~ 69 bytes

*Thanks to xnor for suggesting some changes that saved 3 bytes!*

```
f n=[m|m<-[1..],all((>0).mod(n+m))[2..n+m-1],all((/=m).f)[1..n-1]]!!0

```

Try it online!

I'm new to Haskell, and Haskell golfing, feedback is appreciated!

## Explanation

We define a function `f n`. We define `f n` to be the first element `!!0` of the list:

```
[m|m<-[1..],all((>0).mod(n+m))[2..n+m-1],all((/=m).f)[1..n-1]]

```

Broken down that is:

```
[m|          # Numbers m
m<-[1..],    # From the integers greater than 0
all          # Forall x
(>0).mod(n+m)# n+m mod x is not zero
[2..n+m-1]   # from the integers from 2 to n+m-1
all          # Forall
((/=m).f)    # when f is applied the result is not m
[1..n-1]     # from the integers from 1 to n-1

```
> 15 votes

# Answer
# Jelly, ~~16~~ 15 bytes

```
Rɓ²R+⁸ÆPTḟḢṭµ/Ṫ

```

This assumes **A083569(n) ≤ n²** (the sequence appears to be growing linearly).

Try it online!

### How it works

```
Rɓ²R+⁸ÆPTḟḢṭµ/Ṫ  Main link. Argument: n

R                Range; yield [1, ..., n].
 ɓ               Begin a dyadic chain with swapped arguments.
            µ/   Reduce the range by that chain.
                 If we call the chain f, this computes f(2,1), then f(3,f(2,1)),
                 then f(4,f(3,f(2,1)), etc.
                 The left argument is an integer k, the right one an array A.
  ²                Square; yield k².
   R               Range; yield [1, ..., k²].
    +⁸             Add k, yielding [1+k, ..., k²+k].
      ÆP           Test each sum for primality.
        T          Truth; get all indices of 1‘s. This finds all m in [1, ..., k²]
                   such that m+k is prime.
         ḟ         Filterfalse; remove all resulting elements that appear in A.
          Ḣ        Head; extract the first remaining result.
           ṭ       Tack; append the extracted integer to A.
                 This computes the first n elements of the sequence.
              Ṫ  Tail; extract the last, n-th element.

```
> 6 votes

# Answer
# Pyth - ~~18~~ ~~17~~ 15 bytes

*Thanks to @isaacg for saving me two bytes!*

Back on this site, after being busy for a while, will hopefully golf this one further.

```
esmaYf&-TYP_+Th

```

Try it online here.
> 6 votes

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

```
n=>{if(n<2)return 1;var p=new int[n-1];int i=0,j,s;for(;i<n-1;)p[i]=f(++i);for(i=1;;i++){for(j=2,s=i+n;j<s&&s%j++>0;);if(j==s&!System.Array.Exists(p,e=>e==i))return i;}}

```

Try it online!

By far the most inefficient way to calculate the results, so please refrain from calculating `f(n)` for `n>=30` with this code. The first step is to recursively calculate the values from `f(1)` to `f(n-1)` and then proceed to calculate `f(n)` by searching for the first `i` such that `n+i` is prime and `i` is not in the previous values list.
> 3 votes

# Answer
# x86-64 Assembly, ~~57~~ 55 bytes

I'm new to golfing, so comments/feedback are appreciated.

Note: this is optimized for machine code length, not for source length.

```
0: 89 f8 ff cf 74 32 97 89 fe 89 f1 ff c6 89 f0 99
1: f7 f1 85 d2 e0 f7 85 c9 75 ed 89 f9 ff c9 56 29
2: fe 56 57 51 89 fc e8 d3 ff ff ff 59 5f 5e 39 c6
3: e0 ef 96 5e 74 d1 c3

```

Defines a function, using the standard convention (i.e. return value in eax, first argument in edi, all registers caller-saved except ebx) that takes an unsigned 32-bit integer and returns the smallest m etc.

Source:

```
    .globl a083569
    // edi = original, probably don't touch
    // esi = candidate prime, if it's not a repeat we return edi-this
a083569:
    mov %edi, %eax
    dec %edi
    jz end
    xchg %eax, %edi
    mov %edi, %esi
primecheck:
    mov %esi, %ecx
    inc %esi
primeloop:
    mov %esi, %eax
    cdq
    div %ecx
    test %edx, %edx
    loopnz primeloop
/* end */
    // if esi isn't prime, then ecx is now one or greater.
    test %ecx, %ecx
    jnz primecheck
    // esi is now our target prime: check if it's not already one
    mov %edi, %ecx
    dec %ecx
    push %rsi   /* we need a flag-safe way to restore this later */
    sub %edi, %esi
chkdup:
    push %rsi
    push %rdi
    push %rcx
    mov %ecx, %edi
    call a083569
    pop %rcx
    pop %rdi
    pop %rsi
    cmp %eax, %esi
    loopne chkdup
/* end loop - chkdup */
    xchg %esi, %eax
    pop %rsi
    je primecheck
/* end outer loop - primecheck */
end:
    ret

```

Try it online!
> 3 votes

# Answer
# Python, 194 170 110 bytes

*84 bytes saved by Leaky Nun*

*2 bytes saved by mathmandan*

```
def s(n):
 a=[s(j)for j in range(1,n)];i=1
 while(i in a)|any((i+n)%j<1for j in range(2,i+n)):i+=1
 return i

```

Defines a function s(n) that takes a number as input and returns A083569(n).

Try it Online
> 1 votes

# Answer
## Clojure, ~~158~~ 155 bytes

```
#(loop[r[0 1]i 1](if(= i %)(last r)(recur(conj r(nth(for[j(range):when(=((set r)j)(seq(for[k(range 2(+ 1 i j)):when(=(mod(+ 1 i j)k)0)]j)))]j)0))(inc i))))

```

This might still have some fat, I'm not quite happy with `(+ 1 i j)` but this was the easiest way to handle base case `n = 1` and the rest. `((set r)j)` returns `nil` if `j` is not in the set, and `(seq ())` on an empty list returns nil as well. Calculates `n = 1000` in 48 seconds.

Update: removed `nil` from `=` check as the code works correctly also without it.
> 1 votes

# Answer
# Ruby, 62+8 = 70 bytes

Uses the `-rprime` flag.

```
f=->n,o=[]{o<<f[n-1,o]if n>1;Prime.find{|i|i>n&&o|[i-n]!=o}-n}

```

Try it online!
> 1 votes

# Answer
# Husk, 16 bytes

```
!¡λḟȯṗ+→L¹`-N);1

```

Try it online!

1-indexed.
> 0 votes

---
Tags: code-golf, sequence, primes
---


title: Create a Roman Numeral calculator

text:
# Question
Title: Create a Roman Numeral calculator
Create a basic calculator for Roman numerals.

### Requirements

* Supports `+`,`-`,`*`,`/`
* Input and output should expect only one subtractor prefix per symbol (i.e. 3 can't be `IIV` because there are two `I`'s before `V`)
* Handling of the subtraction principle in input and output must at minimum support modern standard conventions, in which only powers of ten are subtracted from larger numbers (e.g. `I`,`X`,`C` are required subtractors but not `V`,`L`,`D`) and subtraction is never done from a number more than 10x the subtractor (e.g. `IX` must be supported but `IC` is not required).
* Input and output should be left to right in order of value, starting with the largest (i.e. 19 = `XIX` not `IXX`, 10 is larger than 9)
* Left to right, no operator precedence, as if you were using a hand calculator.
* Supports whole positive numbers input/output between 1-4999 (no need for V̅)
* No libraries that do roman numeral conversion for you

### For you to decide

* Case sensitivity
* Spaces or no spaces on input
* What happens if you get a decimal output. Truncate, no answer, error, etc..
* What to do for output that you can't handle. Negatives or numbers to large to be printed.
* Whether to support a more liberal use of the subtraction principle than the minimum requirement.

### Extra Credit

* **-50** \- Handle up to 99999 or larger. Symbols **must** include a vinculum

Sample input/output

```
XIX + LXXX                 (19+80)
XCIX

XCIX + I / L * D + IV      (99+1/50*500+4)
MIV

```

The shortest code wins.

# Answer
> 3 votes
# APL (Dyalog Unicode 18.0), 187 − 50 = 137 bytes (SBCS)

Full program using stdin/stdout. Requires 0-based indexing and space(s) between symbols and numbers.

```
d←,∘⌊⍨'IVXLCD'
'[a-z]'⎕R('\u&',⎕UCS 773)⊢d[∊(2×⌽⍳≢r)+{⍵=⍛⌽⍺0/⍨⍺×⍛⍮⍵-1}⌿0 5⊤1+⍎¨r←⍕⍎∊'\w+'⎕R{⍕(×\1,11⍴5 2)[d⍳⍵.Match](⊣+.×¯1*2</,)0}'(.)\pM'⎕R'\l1'⌽'-' '\*' '/' '\S+'⎕S'-⍨' '×' '÷⍨' '&'⊢⍞]

```

Try it online!

* Full support for vinculum, so 1000 is written as  (`M` is a modern addition)
* Handles all positive results until 899999
* Allows non-standard input, including, e.g. purely additive notation and too large/small subtractors
* Includes support for factorial ! (and actually a bunch of other operations)

# Answer
> 9 votes
# JavaScript (ES6), 238

```
c=s=>{X={M:1e3,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1}
n=eval('W='+s.replace(/[\w]+/g,n=>(o=0,n.replace(/[MDLV]|C[MD]?|X[CL]?|I[XV]?/g,d=>o+=X[d]),
o+';W=W')));o='';for(i in X)while(n>=X[i])o+=i,n-=X[i];return o}

```

Usage:

```
c("XIX + LXXX")
> "XCIX"
c('XCIX + I / L * D + IV')
> "MIV"

```

Annotated version:

```
/**
 * Process basic calculation for roman numerals.
 *
 * @param {String} s The calculation to perform
 * @return {String} The result in roman numerals
 */
c = s => {
  // Create a lookup table.
  X = {
    M: 1e3, CM: 900, D: 500, CD: 400, C: 100, XC: 90,
    L: 50,  XL: 40,  X: 10,  IX: 9,   V: 5,   IV: 4, I: 1
  };
  // Do the calculation.
  //
  // The evaluated string is instrumented to as below:
  //   99+1/50*500+4 -> W=99;W=W+1;W=W/50;W=W*500;W=W+4;W=W
  //                 -> 1004
  n = eval('W=' + s.replace(
    // Match all roman numerals.
    /[\w]+/g,
    // Convert the roman number into an integer.
    n => (
      o = 0,
      n.replace(
        /[MDLV]|C[MD]?|X[CL]?|I[XV]?/g,
        d => o += X[d]
      ),
      // Instrument number to operate left-side operations.
      o + ';W=W'
    )
  ));

  // Convert the result into roman numerals.
  o = '';
  for (i in X)
    while (n >= X[i])
      o += i,
      n -= X[i];

  // Return calculation result.
  return o
}

```

# Answer
> 9 votes
## T-SQL, 1974 - 50 = 1924 bytes

I know that golfing in SQL is equivalent to playing 18 holes with nothing but a sand wedge, but I relished the challenge of this one, and I think I managed to do a few interesting things methodologically.

This does support the vinculum for both input and output. I adopted the convention of using a trailing tilde to represent it , so V~ is 5000, X~ is 10000, etc. It should also handle outputs up to 399,999 according to standard modern Roman numeral usage. After that, it will do partially non-standard Roman encoding of anything in INT's supported range.

Because it's all integer math, any non-integer results are implicitly rounded.

```
DECLARE @i VARCHAR(MAX)
SET @i='I+V*IV+IX*MXLVII+X~C~DCCVI'
SELECT @i

DECLARE @t TABLE(i INT IDENTITY,n VARCHAR(4),v INT)
DECLARE @u TABLE(n VARCHAR(50),v INT)
DECLARE @o TABLE(n INT IDENTITY,v CHAR(1))
DECLARE @r TABLE(n INT IDENTITY,v INT,r VARCHAR(MAX))
DECLARE @s TABLE(v INT,s VARCHAR(MAX))
DECLARE @p INT,@x VARCHAR(4000)='SELECT ',@j INT=1,@m INT,@y INT,@z VARCHAR(2),@q VARCHAR(50)='+-/*~]%'
INSERT @t(n,v) VALUES('i',1),('iv',4),('v',5),('ix',9),('x',10),('xl',50),('l',50),('xc',90),('c',100),('cd',400),('d',500),('cm',900),('m',1000),('mv~',4000),('v~',5000),('mx~',9000),('x~',10000),('x~l~',40000),('l~',50000),('x~c~',90000),('c~',100000)
INSERT @u VALUES('%i[^i'+@q,-2),('%v[^vi'+@q,-10),('%x[^xvi'+@q,-20),('%l[^lxvi'+@q,-100),('%c[^clxvi'+@q,-200),('%d[^dclxvi'+@q,-1000),('%mx~%',-2010),('%x~l~%',-20060),('%x~c~%',-20110)
WHILE PATINDEX('%[+-/*]%', @i)!=0
BEGIN
    SET @p=PATINDEX('%[+-/*]%', @i)
    INSERT @o(v) SELECT SUBSTRING(@i,@p,1)
    INSERT @r(r) SELECT SUBSTRING(@i,1,@p-1)
    SET @i=STUFF(@i,1,@p,'')
END
INSERT @r(r) SELECT @i
UPDATE r SET v=COALESCE(q.v,0) FROM @r r LEFT JOIN (SELECT r.r,SUM(u.v)v FROM @u u JOIN @r r ON r.r LIKE u.n GROUP BY r.r)q ON q.r=r.r
UPDATE r SET v=r.v+q.v FROM @r r JOIN (SELECT r.n,r.r,SUM((LEN(r.r)-LEN(REPLACE(r.r,t.n,REPLICATE(' ',LEN(t.n)-1))))*t.v) v FROM @r r JOIN @t t ON CHARINDEX(t.n,r.r) != 0 AND (LEN(t.n)=1 OR (LEN(t.n)=2 AND RIGHT(t.n,1)='~')) GROUP BY r.n,r.r) q ON q.r=r.r AND q.n = r.n
SELECT @m=MAX(n) FROM @o
SELECT @x=@x+REPLICATE('(',@m)+CAST(v AS VARCHAR) FROM @r WHERE n=1
WHILE @j<=@m
BEGIN
    SELECT @x=@x+o.v+CAST(r.v AS VARCHAR)+')'
    FROM @o o JOIN @r r ON r.n=o.n+1 WHERE o.n=@j
    SET @j=@j+1
END
INSERT @s(v,s) EXEC(@x+',''''')
UPDATE @s SET s=s+CAST(v AS VARCHAR(MAX))+' = '
SET @j=21
WHILE @j>0
BEGIN
    SELECT @y=v,@z=n FROM @t WHERE i = @j
    WHILE @y<=(SELECT v FROM @s)
    BEGIN
        UPDATE @s SET v=v-@y,s=s+@z
    END
    SET @j=@j-1
END
SELECT @x+' = '+UPPER(s) FROM @s

```

I'm still tinkering with a set-based solution to replace some of the WHILE looping that might whittle down the byte count and be a more elegant example of idiomatic SQL. There are also some bytes to be gained by reducing use of table aliases to a bare minimum. But as it's essentially un-winnable in this language, I'm mostly just here to show off my Don Quixote outfit. :)

SELECT @i at the top repeats the input:

```
I+V*IV+IX*MXLVII+X~C~DCCVI

```

And the SELECT at the end returns:

```
SELECT (((((1+5)*4)+9)*1047)+90706) = 125257 = C~X~X~V~CCLVII

```

And you can test it yourself at this SQLFiddle

And I will be returning to add some commentary on how it works, because why post an obviously losing answer if you're not going to exploit it for educational value?

# Answer
> 2 votes
# Javascript - ~~482~~ 476 characters

```
String.prototype.m=String.prototype.replace;eval("function r(a){return a>999?'Mk1e3j899?'CMk900j499?'Dk500j399?'CDk400j99?'Ck100j89?'XCk90j49?'Lk50j39?'XLk40j9?'Xk10j8?'IX':a>4?'Vk5j3?'IV':a>0?'Ik1):''}".m(/k/g,"'+r(a-").m(/j/g,"):a>"));s=prompt();h=s.match(/\w+/gi);for(k in h)s=s.m(h[k],eval(eval("'0'+h[k].m(/IVu4pIXu9pXLu40pXCu90pCDu400pCMu900pMu1000pDu500pCu100pLu50pXu10pVu5pIu1')".m(/u/g,"/g,'+").m(/p/g,"').m(/")))+")");for(k in h)s="("+s;alert(r(Math.floor(eval(s))))

```

The sample input/output works:

```
XIX + LXXX -> XCIX
XCIX + I / L * D + IV -> MIV

```

It badly handles large numbers too:

```
MMM+MMM -> MMMMMM
M*C -> MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

```

And it accepts, but does not requires, spaces too.

But, since I was golfing it has some problems:

* It does not validates if the input is well-formed. If the input is not well-formed, the behaviour is undefined (and in practice it is very bizarre and strange).
* It truncates fraction numbers on output (but it is able to do intermediate calculations with them).
* It really abuses the eval function.
* It does not attempt to handle negative numbers.
* It is case-sensitive.

This alternative version handles numbers over 5000 upto 99999, but it has ~~600~~ ~~598~~ 584 characters:

```
String.prototype.m=String.prototype.replace;eval("function r(a){return a>8zz?'XqCqk9e4j4zz?'Lqk5e4j3zz?'XqLqk4e4jzz?'Xqk1e4j89z?'IqXqk9e3j49z?'Vqk5e3j9z?'Mk1e3j8z?'CMk900j4z?'Dk500j3z?'CDk400jz?'Ck100j89?'XCk90j49?'Lk50j39?'XLk40j9?'Xk10j8?'IX':a>4?'Vk5j3?'IV':a>0?'Ik1):''}".m(/k/g,"'+r(a-").m(/j/g,"):a>").m(/q/g,"\u0305").m(/z/g,"99"));s=prompt();h=s.match(/\w+/gi);for(k in h)s=s.m(h[k],eval(eval("'0'+h[k].m(/IVu4pIXu9pXLu40pXCu90pCDu400pCMu900pMu1000pDu500pCu100pLu50pXu10pVu5pIu1')".m(/u/g,"/g,'+").m(/p/g,"').m(/")))+")");for(k in h)s="("+s;console.log(r(Math.floor(eval(s))))

```

# Answer
> 2 votes
## Javascript ~~479~~ ~~361~~ ~~348~~ ~~278~~ 253

303 characters - 50 for supporting numbers up to 1 million, complete with vinculum support:

```
function p(s){s=s[r](/(^|[*\/+-])/g,"0;s$1=");for(i in v){f=R("\\b"+i);while(f.test(s))s=s[r](f,v[i]+"+")}eval(s+"0");h="";for(i in v)while(s>=v[i]){h+=i;s-=v[i]}return h}v={M̅:1e6,D̅:5e5,C̅:1e5,L̅:5e4,X̅:1e4,V̅:5e3,M:1e3,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1};r="replace";R=RegExp

```

Usage: `p(text)`, e.g., `p('XIX + LXXX')` returns `XCIX`.

Code with explanatory comments:

```
// Array mapping characters to values
v={M¯:1e6,D¯:5e5,C¯:1e5,L¯:5e4,X¯:1e4,V¯:5e3,M:1e3,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1};
// Shortcut for String.replace
r='replace';
R=RegExp;

// The heart of the program
function p(s) {
    // Replace operators with ";s+=", ";s-=", and so on
    s=s[r](/(^|[*\/+-])/g,'0;s$1=');
    // Loop over the character map and replace all letters with numbers
    for(i in v){
        f=R('\\b'+i);
        while(f.test(s))
            s=s[r](f, v[i]+'+')
    }
    eval(s+'0');
    // Set up our return string
    h='';
    // Replace digits with characters
    for(i in v)
        while(s>=v[i]) {
            h+=i;
            s-=v[i];
        }
    return h;
}

```

This works for the given samples and for all others I have tried. Examples:

```
XIX + LXXX = XCIX
XCIX + I / L * D + IV = MIV
XL + IX/VII + II * XIX = CLXXI
CD + C + XL + X + I = DLI
M̅ + I = M̅I
MMMM + M = V̅

```

# Answer
> 2 votes
## Ruby 2.1, 353 (and *many* other iterations), 295 - 50 = 245

The vinculum handling adds ~23 characters.

This handles "IL" or "VM" in the input, and fails without error on negatives (goes to high ints) or decimals (truncates), or any spaces. Now also handles a negative first number (though if the total is negative, it still fails poorly). Also fails poorly if you start with * or / or if the result is 4 million or larger.

Uses Object#send for "hand-calculator" functionality.

```
m=%w{I V X L C D M V̅ X̅ L̅ C̅ D̅ M̅};n=m.zip((0..12).map{|v|(v%2*4+1)*10**(v/2)}).to_h
d=0
gets.scan(/([-+*\/])?([A-Z̅]+)/){|o,l|f=t=0
l.scan(/.̅?/){t-=2*f if f<v=n[$&]
t+=f=v}
d=d.send o||:+,t}
7.downto(1){|v|z=10**v
y=(d%z)*10/z
q,w,e=m[v*2-2,3]
$><<(y>8?q+e : y<4?q*y : y<5?q+w : w+q*(y-5))}

```

Ungolfed:

```
m=%w{I V X L C D M V̅ X̅ L̅ C̅ D̅ M̅} # roman numerals
n=m.zip((0..12).map{|v|(v%2*4+1)*10**(v/2)}).to_h # map symbols to values
d=0
gets. # get input and...
  scan(/([-+*\/])?([A-Z̅]+)/) { |l,o|  # for each optional operator plus number
    f=t=0
    l.scan(/.̅?/){                           # read the number in one letter at a time
      t -= 2 * f if f < (v=n[$&])           # if the number's greater than the prev, subtract the prev twice since you already added it
      t += (f = v)                          # add this, and set prev to this number
    }
    d = d.send((o || :+), t)                # now that we've built our number, "o" it to the running total (default to +)
}
7.upto(1) { |v|                        # We now print the output string from left to right
  z = 10**v                            # z = [10, 100, 1000, etc.]
  y = (d%z)*10/z                       # if d is 167 and z is 100, y = 67/10 = 6
  q,w,e = m[v*2-2,3]                   # q,w,e = X, L, C
  $><< (                               # print:
    y>8 ? q+e :                        # if y==9,    XC
      y<4 ? q*y :                      # if y<4,     X*y
        y>3 ? q+w :                    # if y==4,    XL
          q*(y-5)                      # else,       L + X*(y-5)
  )
}

```

# Answer
> 2 votes
# Python 2 - ~~427~~ ~~418~~ ~~404~~ ~~401~~ ~~396~~ ~~395~~ 392 characters

Reads from standard input. It only handles uppercase (could make it case-insensitive at the cost of 8 extra characters) and requires spaces. Does no validation--I haven't tested to see how it breaks in various cases. It does, however, handle numbers like VC = 95.

```
N=['?M','DC','LX','VI'];t=0;o='+'
for q in raw_input().split():
 if q in"+-*/":o=q;continue
 n=s=0;X=1
 for l in q:
  x=''.join(N).find(l);v=(5-x%2*4)*10**(3-x/2)
  if X<x:n+=s;s=v;X=x
  elif X>x:n+=v-s;s=0
  else:n+=v+s;s=0
 exec"t"+o+"=n+s"
r=t/1000*'M'
for p,d in enumerate("%04d"%(t%1e3)):
 i="49".find(d);g=N[p]
 if i<0:
  if'4'<d:r+=g[0]
  r+=int(d)%5*g[1]
 else:r+=g[1]+N[p-i][i]
print r

```

And the ungolfed version:

```
# Numerals grouped by powers of 10
N = ['?M','DC','LX','VI']
# Start with zero plus whatever the first number is
t = 0
o = '+'
for q in raw_input().split():
    if q in "+-*/":
        # An operator; store it and skip to the next entry
        o = q
        continue
    # n holds the converted Roman numeral, s is a temp storage variable
    n = s = 0
    # X stores our current index moving left-to-right in the string '?MDCLXVI'
    X = 1
    for l in q:
        # x is the index of the current letter in '?MDCLXVI'
        x = ''.join(N).find(l)
        # Calculate the value of this letter based on x
        v = (5 - x%2 * 4) * 10 ** (3 - x/2)
        if X < x:
            # We're moving forward in the list, e.g. CX
            n += s      # Add in any previously-stored value
            s = v       # Store this value in case we have something like CXL
            X = x       # Advance the index
        elif X > x:
            # Moving backward, e.g. XC
            n += v - s  # Add the current value and subtract the stored one
            s=0
        else:
            # Same index as before, e.g. XX
            n += v + s  # Add the current value and any stored one
            s = 0
    # Update total using operator and value (including leftover stored value
    # if any)
    exec "t" + o + "=n+s"

# Now convert the answer back to Roman numerals
# Special-case the thousands digit
r = t / 1000 * 'M'
# Loop over the number mod 1000, padded with zeroes to four digits (to make
# the indices come out right)
for p, d in enumerate("%04d" % (t % 1e3)):
    i = "49".find(d)
    g = N[p]
    if i < 0:
        # i == -1, thus d isn't '4' or '9'
        if '4' < d:
            # >= 5, so add the 5's letter
            r += g[0]
        # ... plus (digit % 5) copies of the 1's letter
        r += int(d) % 5 * g[1]
    else:
        # If it's a 4 or 9, add the 1's letter plus the appropriate
        # larger-valued letter
        r += g[1] + N[p-i][i]
print r

```

I have a feeling Perl would have been better, but I don't know enough of it. For a first stab at code golf, though, I feel pretty good about this.

# Answer
> 1 votes
# PHP — ~~549~~ ~~525~~ ~~524~~ 520 bytes

Nothing too innovative: normalizes the operators to ensure left to right precedence, converts Roman to decimal, runs `eval` on the statement, e.g. *XCIX + I / L * D + IV* is converted to something like *return (((((+90 +9) + (+1)) / (+50)) * (+500)) + (+4));*, then converts decimal back to Roman.

* final results are truncated
* answers less than 1 come back blank
* results are undefined if given incorrect input

```
$f='str_replace';$g='str_split';$c=array('M'=>1e3,'CM'=>900,'D'=>500,'CD'=>400,'C'=>100,'XC'=>90,'L'=>50,'XL'=>40,'X'=>10,'IX'=>9,'V'=>5,'IV'=>4,'I'=>1);$j='['.$f(array('+','-','*','/'),array('])+[','])-[','])*[','])/['), $argv[1]).'])';$j=str_repeat('(',substr_count($j,')')).$j;$j=$f('[','(',$j);$j=$f(']',')',$j);foreach($g('IVIXXLXCCDCM',2)as$w)$j=$f($w,'+'.$c[$w],$j);foreach($g('IVXLCDM')as$w)$j=$f($w,'+'.$c[$w],$j);$k=eval('return '.$j.';');$l='';foreach($c as$a=>$b){while($k>=$b){$l.=$a;$k-=$b;}}print$l."\n";
```

e.g.

```
$ php roman.php 'XCIX + I / L * D + IV' — test case
MIV                                     — 1004

$ php roman.php 'XXXII * LIX'           — 32 × 59
MDCCCLXXXVIII                           — 1888

```

# Answer
> 1 votes
# Python - 446 bytes

This could be improved considerably. I felt I had to take the first swing using Python. It does 3 things on the first pass

1. tokenizes the numbers and operators
2. evaluates the numbers, and enlarges the symbol table `x` to include all possible combinations encountered (even if they are not used). For example, while `XIX` is being lexed, the partial values of `"X":10`, `"XI":11` and `"XIX":19` are added to the symbol table
3. inserts nested parens to enforce left-to-right evaluation

At the end, it calls `eval` on the original string (except with added parens) and gives it the symbol table.

Then I just pasted in a known solution to convert integer to Roman, since I had worked on this long enough... please feel free to improve so that I learn something new :)

```
m=zip((1000,900,500,400,100,90,50,40,10,9,5,4,1),
('M','CM','D','CD','C','XC','L','XL','X','IX','V','IV','I'))
def doit(s):
 x={'M':1e3,'D':500,'C':100,'L':50,'X':10,'V':5,'I':1};y=[];z='';a='0';s='+'+s
 for c in s.upper():
  if c in x:
   z+=c;y.append(x[c])
   if len(y)>1and y[-1]>y[-2]:y[-2]*=-1
   x[z]=sum(y)
  elif c in"+/*-":a='('+a+z+')'+c;y=[];z=''
 a+=z;i=eval(a,x);r = ''
 for n,c in m:d=int(i/n);r+=c*d;i-=n*d
 return r

print doit("XIX + LXXX")
print doit("XCIX + I / L * D + IV")

```

# Answer
> 1 votes
## MATLAB - 543 bytes

I tried not to look at others' answers before working on my own, although my approach ended up similar regardless. I use a regular expression to match word characters (the numbers) or operators, which splits up the input into a cell array alternating between numbers and operators. I then replace the roman numerals in every other cell with itself and a plus sign, using order of precedence on the groups to ensure proper grouping. I define variables with the same name as each split group and use an eval statement on the split roman numeral to convert it to a value with a closing parenthese. I then concatenate the whole list of values and operators with proper opening parentheses to ensure strict left-to-right order of operations. I then deconstruct the resulting number digit-by-digit and convert it to the proper roman numeral based on its "power".

```
function n=m(I)
e=regexp(I,'\w+|[\+\-\*\/]','match');CM=900;XC=90;IX=9;CD=400;XL=40;IV=4;M=1e3;D=500;C=100;L=50;X=10;V=5;I=1;e(1:2:end)=cellfun(@(x) [num2str(evalin('caller',[x '0'])) ')'],regexprep(e(1:2:end),'CM|XC|IX|CD|XL|IV|.?','$0+'),'un',0);S=num2str(eval(strcat(repmat('(',1,(length(e)+1)/2),e{:})));n='';I='IXCM';V='VLD ';l=length(S);for i=1:l
p=l-i+1;a=eval(S(i));if p>3
n=repmat('M',1,a);continue
end
b=a>4;switch a
case 4
n=[n I(p) V(p)];case 9
n=[n I(p:p+1)];otherwise
n=[n repmat(V(p),1,b) repmat(I(p),1,a-5*b)];end
end

```

ungolfed:

```
function n=m(I)
e=regexp(I,'\w+|[\+\-\*\/]','match'); % match roman numerals or operators
CM=900;XC=90;IX=9; % nines
CD=400;XL=40;IV=4; % fours
M=1e3;D=500;C=100; % single character numbers (ones and fives)
L=50;X=10;V=5;I=1;
e(1:2:end)=cellfun(@(x) [num2str(evalin('caller',[x '0'])) ')'],... % Evaluate each group and add a parenthesis
                   regexprep(e(1:2:end),'CM|XC|IX|CD|XL|IV|.?','$0+'),'un',0); % replace each group or single digit with itself and a +
S=num2str(eval(strcat(repmat('(',1,(length(e)+1)/2),e{:}))); % concatenate the split string and evaluate with proper parentheses for left-to-right Order of Operations
n='';         % initialize output
I='IXCM';     % Define ones and fives
V='VLD ';
l=length(S);
for i=1:l
p=l-i+1;
a=eval(S(i));
if p>3              % if the number has 4 or more digits, just add a bunch of Ms
n=repmat('M',1,a);
continue
end
b=a>4;
switch a
case 4
n=[n I(p) V(p)]; % If the digit is 4, add the proper 1 and 5
case 9
n=[n I(p:p+1)]; % If the digit is 9, add the correct 9 group
otherwise
n=[n repmat(V(p),1,b) repmat(I(p),1,a-5*b)]; % Add a 5 if the digit is greater than 4. add 1s for either the digit value (1,2,3) or the value - 5 (6,7,8)
end
end

```

---
Tags: code-golf, roman-numerals
---


title: I ain't no Fortunate sum

text:
# Question
Title: I ain't no Fortunate sum
The primorial \\$p\_n\\#\\$ is the product of the first \\$n\\$ primes. The sequence begins \\$2, 6, 30, 210, 2310\\$.

A Fortunate number, \\$F\_n\\$, is the smallest integer \\$m \> 1\\$ such that \\$p\_n\\# + m\\$ is prime. For example \\$F\_7 = 19\\$ as:

$$p\_7\\# = 2\times3\times5\times7\times11\times13\times17 = 510510$$

Adding each number between \\$2\\$ and \\$18\\$ to \\$510510\\$ all yield composite numbers. However, \\$510510 + 19 = 510529\\$ which is prime.

The Fortunate numbers below \\$200\\$ are

$$3, 5, 7, 13, 17, 19, 23, 37, 47, 59, 61, 67, 71, 79, 89, 101, 103, 107, 109, 127, 151, 157, 163, 167, 191, 197, 199$$

We'll say an integer \\$n\\$ is a "Fortunate sum" if it can be expressed as the sum of two distinct Fortunate numbers. For example, \\$22 = 3 + 19 = 5 + 17\\$, so \\$22\\$ can be expressed as the sum of two Fortunate numbers, and so is a "Fortunate sum"

You are to take an integer \\$n\\$ as input and output a truthy value if \\$n\\$ is a Fortunate sum and a falsey value otherwise. You may swap the order (falsey indicates it is a Fortunate sum) if you wish. You may take input and output in any convenient format.

This is so the shortest code in bytes wins

## Test cases

The first line is the Fortunate sums less than 100 (truthy values) and the second are the integers less than or equal to 100 that aren't Fortunate sums

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

```

# Answer
# Haskell, <sup>~~130~~</sup> 128 bytes

```
a n=or[f x&&f(n-x)|x<-[2..n],2*x<n]
f m=or[and[p(x+y)/=(y<m)|y<-[2..m]]|x<-scanl1(*)$filter p[2..m]]
p n=all((>0).mod n)[2..n-1]

```

Try it online!

This solution is based on the following observation.

**Fact.** An integer \\$m\>1\\$ is Fortunate if and only if, for some prime number \\$p\_n\<m\\$, \\$m\\$ is the smallest integer \\$\>1\\$ such that \\$ p\_1 p\_2\cdots p\_n+m \\$ is prime.

*Proof.* The claim follows easily from the fact that if \\$p\_n\ge m\\$ then there is some \\$p\_i\\$ with \\$i\le n\\$ such that \\$p\_i\mid m\\$, and therefore \\$p\_i\mid p\_1 p\_2\cdots p\_n+m\\$.

At this point, checking if a number \\$m\\$ is Fortunate is trivial: we just have to check the condition for all the prime numbers up to \\$m\\$.

## Explanation of the code

```
p n=all((>0).mod n)[2..n-1]

```

The standard prime-checking function. Only works for `n>1`, but that's ok.

---

```
f m=or[and[p(x+y)/=(y<m)|y<-[2..m]]|x<-scanl1(*)$filter p[2..m]]

```

A function to check whether a number `m` is Fortunate. As explained above, it calculates the primorials \\$\texttt{x}=p\_1p\_2\cdots p\_n\\$ until \\$p\_n\le\texttt{m}\\$ and tests whether `m` is the smallest integer \\$\texttt{y}\>1\\$ such that \\$\texttt{x}+\texttt{y}\\$ is prime.

---

```
a n=or[f x&&f(n-x)|x<-[2..n],2*x<n]

```

The final function, to check whether `n` is a Fortunate sum. Pretty straightforward, the only thing to be careful of is that `x` and `n-x` must be different: this is the reason why we only iterate over values of `x` such that `2*x<n`.
> 7 votes

# Answer
# Wolfram Language (Mathematica), 106 bytes

```
Check[Tr[1^Union[#&@@IntegerPartitions[#,{2},Array[NextPrime[a=Times@@Array[Prime,#]+1]-a+1&,#]]]]>1,1>2]&

```

Try it online!
> 3 votes

# Answer
# Jelly,  ~~14~~  13 bytes

-1 thanks to ChartZBelatedly! (use the built-in for choose-2.)

Thanks to Delfad0r for the simple explanation in their Haskell answer proving that this works, I probably would not have posted it otherwise!

```
ÆRPƤ‘Æn_ƊŒc§ċ

```

A monadic Link accepting an integer \\$n\\$ that yields a positive integer if \\$n\\$ is a Fortunate Sum, or zero if not.

**Try it online!** Or see A split of \\$n\leq 100\\$ into non-Fortunate and Fortunate Sums.

### How?

```
ÆRPƤ‘Æn_ƊŒc§ċ - Link: integer, n                e.g. 18
ÆR            - primes between 2 and n inclusive     [2,3, 5, 7,  11,  13,   17]
   Ƥ          - for prefixes:
  P           -   product                            [2,6 ,30,210,2310,30030,510510]
        Ɗ     - last three links as a monad, f(x=that):
    ‘         - increment (x)                        [3,7 ,31,211,2311,30031,510511]
     Æn       -   next, strictly greater, prime      [5,11,37,223,2333,30047,510529]
       _      -   subtract (x)                       [3,5, 7, 13, 23,  17,   19]
         Œc   - choose-2                             [[3,5],[3,7],[3,13],[3,23],[3,17],[3,19],[5,7],[5,13],[5,23],[5,17],[5,19],[7,13],[7,23],[7,17],[7,19],[13,23],[13,17],[13,19],[23,17],[23,19],[17,19]]
           §  - sums                                 [8,10,16,26,20,22,12,18,28,22,24,20,30,24,26,36,30,32,40,42,36]
            ċ - count occurrences (of n)             1 (truthy)

```
> 3 votes

# Answer
# 05AB1E, ~~35~~ ~~31~~ ~~29~~ 28 bytes

```
Lʒ©ÅPηPε2®Ÿ+pJΘ}à}ãʒË_}OI¢Íd

```

Try it online!

-4 bytes thanks to ovs

A port of Delfad0r's Haskell answer.
> 2 votes

---
Tags: code-golf, decision-problem, primes, integer-partitions
---


title: Expand Kirkman's Schoolgirl Problem

text:
# Question
Title: Expand Kirkman's Schoolgirl Problem
For those of you who are unfamiliar, Kirkman's Schoolgirl Problem goes as follows:

> Fifteen young ladies in a school walk out three abreast for seven days in succession: it is required to arrange them daily so that no two shall walk twice abreast.

We could look at this like a nested *3* by *5* list (or matrix):

```
[[a,b,c]
 [d,e,f]
 [g,h,i]
 [j,k,l]
 [m,n,o]]

```

Essentially, the goal of the original problem is to figure out 7 different ways to arrange the above matrix so that two letters *never share a row more than once*. From MathWorld (linked above), we find this solution:

```
[[a,b,c]   [[a,d,h]   [[a,e,m]   [[a,f,i]   [[a,g,l]   [[a,j,n]   [[a,k,o]
 [d,e,f]    [b,e,k]    [b,h,n]    [b,l,o]    [b,d,j]    [b,i,m]    [b,f,g]
 [g,h,i]    [c,i,o]    [c,g,k]    [c,h,j]    [c,f,m]    [c,e,l]    [c,d,n]
 [j,k,l]    [f,l,n]    [d,i,l]    [d,k,m]    [e,h,o]    [d,o,g]    [e,i,j]
 [m,n,o]]   [g,j,m]]   [f,j,o]]   [e,g,n]]   [i,k,n]]   [f,h,k]]   [h,l,m]]

```

Now, what if there were a different number of schoolgirls? Could there be an eighth day? This is our challenge.

In this case no††, but not necessarily for other array dimensions
††We can easily show this, since `a` appears in a row with every other letter.

---

## The Challenge:

Given an input of dimensions (rows, than columns) of an array of schoolgirls (i.e. `3 x 5`, `4 x 4`, or `[7,6]`, `[10,10]`, etc.), output the largest possible set of 'days' that fit the requirements specified above.

**Input:**
The dimensions for the schoolgirl array (any reasonable input form you wish).

**Output:**
The largest possible series of arrays fitting the above requirements (any reasonable form).

**Test Cases:**

```
Input:  [1,1]
Output: [[a]]

Input:  [1,2]
Output: [[a,b]]

Input:* [2,1]
Output: [[a]
         [b]]

Input:  [2,2]
Output: [[a,b]  [[a,c]  [[a,d]
         [c,d]]  [b,d]]  [b,c]]

Input:  [3,3]
Output: [[a,b,c]  [[a,d,g]  [[a,e,i]  [[a,f,h]
         [d,e,f]   [b,e,h]   [b,f,g]   [b,d,i]
         [g,h,i]]  [c,f,i]]  [c,d,h]]  [c,e,g]]

Input:  [5,3]
Output: [[a,b,c]   [[a,d,h]   [[a,e,m]   [[a,f,i]   [[a,g,l]   [[a,j,n]   [[a,k,o]
         [d,e,f]    [b,e,k]    [b,h,n]    [b,l,o]    [b,d,j]    [b,i,m]    [b,f,g]
         [g,h,i]    [c,i,o]    [c,g,k]    [c,h,j]    [c,f,m]    [c,e,l]    [c,d,n]
         [j,k,l]    [f,l,n]    [d,i,l]    [d,k,m]    [e,h,o]    [d,o,g]    [e,i,j]
         [m,n,o]]   [g,j,m]]   [f,j,o]]   [e,g,n]]   [i,k,n]]   [f,h,k]]   [h,l,m]]

There may be more than one correct answer.

```

\*Thanks to @Frozenfrank for correcting test case **3**: if there is only one column, there can only be one day, since row order does not matter.

This is competition - shortest answer wins.

# Answer
> 12 votes
# Mathematica, 935 bytes

```
Inp={5,4};L=Length;T=Table;ST[t_,k_,n_]:=Binomial[n-1,t-1]/Binomial[k-1,t-1];H=ToExpression@Alphabet[];Lo=Inp[[1]]*Inp[[2]];H=H[[;;Lo]];Final={};ST[2,3,12]=4;ST[2,4,20]=5;If[Inp[[2]]==1,Column[Partition[H,{1}]],CA=Lo*Floor@ST[2,Inp[[2]],Lo];While[L@Flatten@Final!=CA,Final={};uu=0;S=Normal[Association[T[ToRules[H[[Z]]==Prime[Z]],{Z,L@H}]]];PA=Union[Sort/@Permutations[H,{Inp[[2]]}]];PT=Partition[H,Inp[[2]]];While[L@PA!=0,AppendTo[Final,PT];Test=Flatten@T[Times@@@Subsets[PT[[X]],{2}]/.S,{X, L@PT}];POK=T[Times@@@Subsets[PA[[Y]],{2}]/.S,{Y,L@PA}];Fin=Select[POK,L@Intersection[Test,#]==0&];Facfin=T[FactorInteger[Fin[[V]]],{V,L@Fin}];end=T[Union@Flatten@T[First/@#[[W]],{W,L@#}]&[Facfin[[F]]],{F,L@Facfin}]/.Map[Reverse,S];PA=end;PT=DeleteDuplicates[RandomSample@end,Intersection@##=!={}&];If[L@Flatten@PT<L@H,While[uu<1000,PT=DeleteDuplicates[RandomSample@end,Intersection@##=!={}&];If[L@Flatten@PT==L@H,Break[],uu++]]]]];Grid@Final]

```

this is for ***26 ladies max***

**EDIT**
I made some changes and I think it works! The code right now is set to solve \[5,4\] (which is the "social golfers problem") and gets the result in a few seconds. However \[5,3\] problem is tougher and you will have to **wait** 10-20 minutes but you **will get** a right combination for all days. For easier cases it is very quick.

anyway you can try it and see the results
**Try it online here**
copy and paste using ctrl-v
press shift+enter to run the code
you can change the input at the begining of the code -\> Inp={5,4}
run the code multiple times to get different permutations

# Answer
> 3 votes
# Jelly, 19 bytes

```
×Œ!s€ɗœcⱮ×ẎẎṢ€QƑƊƇṪ

```

Try it online!

The Footer simply formats the input and output and demonstrates for various inputs. Assumes that it's ok to return any valid configuration, rather than the one stated in the question.

This is a brute force approach and isn't efficient by any meaning of the word. If we call the dimensions \\$n\\$ and \\$m\\$ (\\$n\\$ being height), this generates

$$f(n, m) = \sum^{nm}\_{i=1} \binom {(nm)!} {i}$$

lists to check. For example, for \\$n = 3, m = 5\\$, we generate $$42755752626996476442177192901690329126386272975917980316235035492211700060653916251199050827754168292191219682093923414635027126605138973495697914193291687743693535776000$$

lists to check. Unsurprisingly, this times out on TIO for basically all inputs. Those for which it doesn't time out are shown in the TIO link.

## How it works

```
×Œ!s€ɗœcⱮ×ẎẎṢ€QƑƊƇṪ - Main link. Takes n on the left and m on the right
     ɗ              - Group the previous 3 links into a dyad f(n, m):
×                   -   Yield n×m
 Œ!                 -   Promote n×m into a range [1, 2, ..., n×m] and yield
                         all permutations of that range
    €               -   Over each permutation:
   s                -     Split it into an n×m matrix
         ×          - Yield n×m
        Ɱ           - For each integer 1 ≤ i ≤ n×m:
      œc            -   Yield all combinations (without replacement) of the
                         permutations of length i
          Ẏ         - Tighten these into a single list of lists of matrices
                ƊƇ  - Keep those for which the following is true:
              QƑ    -   The matrix has no duplicates when:
           Ẏ        -     Tightened into a list of lists
            Ṣ€      -     And each list is sorted
                  Ṫ - Get the last (i.e. the longest) such list

```

---
Tags: code-golf, math, array
---