What?

Schantz 2017 Coding Competition

Who?

Christian Iversen ci@iversenit.dk

  • Bender of rules
  • Torturer of compilers
  • Destroyer of style guides

Why?

How?


#!/usr/bin/python3

initial_year    = 2016
initial_reserve = 0.0

small_payment = 10000.0
large_payment = 20000.0
large_payment_start = 2030

small_customer_fee = 1000.0
small_customer_limit = 200000.0

interest_pal_fee = 0.1530
interest_rate = 0.01

payment_fee = 0.1100
...

...
def calc_year(year):
    if year == initial_year:
        return initial_reserve
    else:
        Rn_last = calc_year(year - 1)
        if year >= large_payment_start:
            I = large_payment
        else:
            I = small_payment
        Opct = I * payment_fee
        if Rn_last > small_customer_limit:
            Oabs = 0
        else:
            Oabs = small_customer_fee
        r = interest_rate * (Rn_last + I - Opct - Oabs)
        PAL = interest_pal_fee * r
        res = Rn_last + I - Opct - Oabs + r - PAL
        return res
...

...
for year in range(2016, 3000):
    amount = calc_year(year)
    print("%d\t%.6f" % (year, amount))
    if amount > 1000000.0:
        break

1089 chars


interface X {
    static void main(String[]a) {
        float Rn = 0.0f;
        float Rn_last = 0.0f;
        for (int year = 2016; Rn_last < 1e6; year++) {
            Rn_last = Rn;
            float I, Oabs, Opct, r, PAL;
            if (year >= 2029) {
                I = 20000;
            } else {
                I = 10000;
            }
            Opct = I * 0.1100f;
            if (Rn_last > 200000) {
                Oabs = 0;
            } else {
                Oabs = 1000;
            }
            r = 0.01f * (Rn_last + I - Opct - Oabs);
            PAL = 0.1530f * r;
            Rn = Rn_last + I - Opct - Oabs + r - PAL;
            System.out.format("%d	%f\n", year, Rn_last);
       }
    }
}

360 chars


interface X {
    static void main(String[]a) {
        float Rn = 0f;
        float L = 0f;
        for (int Y = 2016; L < 1e6; Y++) {
            L = Rn;
            float I, A, Opct, r, P;
            if (Y >= 2029) {
                I = 2e4f;
            } else {
                I = 1e4f;
            }
            Opct = I * 0.1100f;
            if (L > 2e5) {
                A = 0;
            } else {
                A = 1000;
            }
            float X = L + I - Opct - A;
            float Z = 0.01f * X;
            Rn = X + 0.847f * Z;
            System.out.format("%d       %f\n", Y, L);
       }
    }
}

274 chars


interface X {
    static void main(String[]a) {
        float Rn = 0f;
        float L = 0f;
        for (int Y = 2016; L < 1e6; Y++) {
            L = Rn;
            float I, Opct, r, P;
            I = 1e4f * (Y >= 2029 ? 2 : 1);
            Opct = I * 0.1100f;
            float X = L + I - Opct - (L > 2e5 ? 0 : 1000);
            Rn = 1.00847f * X;
            System.out.format("%d       %f\n", Y, L);
       }
    }
}

229 chars


interface X {
    static void main(String[]a) {
        float L = 0f;
        float X = 0;
        float Q = 0;
        for (int Y = 2015; Q < 1e6; Y++) {
            L = 1.00847f * X;
            float I, r, P;
            I = 1e4f * (Y > 2027 ? 2 : 1);
            X = L + I - (I * 0.1100f) - (L > 2e5 ? 0 : 1000);
            System.out.format("%d       %f\n", Y, L);
            Q = L;
        }
    }
}

215 chars


interface X {
    static void main(String[]a) {
        float X = 0;
        for (int Y = 0; Y < 70; Y++) {
            System.out.format("%d       %f\n", Y+2016, X *= 1.00847f);
            X += (1e4f * (Y > 12 ? 2 : 1) * 0.89f) - (X > 2e5 ? 0 : 1e3);
        }
    }
}

164 chars


interface X {
    static void main(String[]a) {
        float X = 0;
        for (int Y = 0; Y < 70; Y++) {
            System.out.format("%d       %f\n", Y+2016, X *= 1.00847f);
            X += 8900 * (Y > 12 ? 2 : 1) - (X > 2e5 ? 0 : 1e3);
        }
    }
}

156 chars


interface X {
    static void main(String[]a) {
        float Y = 16, X = 0;
        while (Y++ < 71) {
            System.out.format("20%f     %f\n", Y, X *= 1.00847f);
            X -= X > 2e5 ? 0 : 1e3;
            X += Y > 29 ? 17800 : 8900;
        }
    }
}

151 chars


interface X {
    static void main(String[]a) {
        for (
            float Y = 16, X = 0;
            Y++ < 71;
            X -= X > 2e5 ? 0 : 1e3, X += Y > 29 ? 17800 : 8900
        ) System.out.format("20%f       %f\n", Y, X *= 1.00847);
    }
}

146 chars


interface X {
    static void main(String[]a) {
        for (
            float Y = 16, X = 0;
            Y++ < 71;
            X += Y > 29 ? Y > 35 ? 17800 : 16800 : 7900
        ) System.out.format("20%f       %f\n", Y, X *= 1.00847);
    }
}

142 chars


interface X {
    static void main(String[]a) {
        for (
            long Y = 16, X = 0;
            Y++ < 71;
            X += (Y > 29 ? Y > 35 ? 178 : 168 : 79) * 100
        ) System.out.format("20%d       %d\n", Y, X *= 1.00847);
    }
}

141 chars


interface X {
    static void main(String[]a) {
        for (
            int Y = 16, X = 0;
            Y++ < 71;
            X += (Y > 29 ? Y > 35 ? 178 : 168 : 79) * 100
        ) System.out.format("20%d       %d\n", Y, X *= 1.0085);
    }
}

139 chars


interface X {
    static void main(String[]a) {
        for (
            int Y = 16, X = 0;
            Y++ < 71;
            X += (Y > 29 ? Y > 35 ? 178 : 168 : 79) * 100
        ) System.out.format("20%d       %d\n", Y, X += X/118);
    }
}

138 chars


interface X {
    static void main(String[]a) {
        for (
            int Y = 16, X = 0;
            Y++ < 71;
            X += (Y > 29 ? Y > 35 ? 278 : 262 : 123) << 6
        ) System.out.format("20%d       %d\n", Y, X += X/118);
    }
}

138 chars


interface X {
    static void main(String[]a) {
        for (
            int Y = 15, X = 0;
            Y++ < 70;
            X += Y > 28 ? 524 + Y / 35 * 32 << 5 : 7904
        ) System.out.format("20%d       %d\n", Y, X += X / 118);
    }
}

136 chars

Mistakes were made..


/* beanshell is not java */
for (
    Y = 15, X = 0;
    Y++ < 70;
    X += Y > 28 ? 524 + Y / 35 * 32 << 5 : 7900
) print("20" + Y + "    " + (X += X / 118));

77 chars (but against the rules)


class P
{
    static void Main()
    {
        for (
            int Y = 15, X = 0;
            Y++ < 70;
            X += (Y > 28 ? Y > 35 ? 556 : 524 : 247) << 5
        ) System.Console.Write("20{0}	{1}\n", Y, X += X/118);
    }
}

130 chars


class P
{
    static void Main()
    {
        for (
            int Y = 15, X = 0;
            Y++ < 70;
            X += Y > 28 ? 524 + Y / 35 * 32 << 5 : 7904
        ) System.Console.Write($"20{Y}  {X += X/118}\n");
    }
}

125 chars

Wait, what?


X += Y > 28 ? 524 + Y / 35 * 32 << 5 : 7904
  

/*     unternarize!     */
if (Y > 28) {
  X += 524 + Y / 35 * 32 << 5
} else {
  X += 7904
}
  

/*     still weird     */
  X += 524 + Y / 35 * 32 << 5
  

/*     ..but 34*2 < 70 :-(     */
  X += 524 + (Y > 34 ? 1: 0) * 32
  

And what's the deal with airline food the number 7904?

Isn't it supposed to be 7900?

2016:       0.0000 vs ref       0.0000: diff       0.0000 (   0.000% error) |          |          |          |          |
2017:    7970.0000 vs ref    7966.9130: diff       3.0870 (  38.748% error) |          |          |***       |          |
2018:   16008.0000 vs ref   16001.3058: diff       6.6942 (  41.836% error) |          |          |****      |          |
2019:   24114.0000 vs ref   24103.7498: diff      10.2502 (  42.525% error) |          |          |****      |          |
2020:   32289.0000 vs ref   32274.8216: diff      14.1784 (  43.930% error) |          |          |****      |          |
2021:   40533.0000 vs ref   40515.1023: diff      17.8977 (  44.175% error) |          |          |****      |          |
2022:   48847.0000 vs ref   48825.1782: diff      21.8218 (  44.694% error) |          |          |****      |          |
2023:   57231.0000 vs ref   57205.6405: diff      25.3595 (  44.330% error) |          |          |****      |          |
2024:   65686.0000 vs ref   65657.0853: diff      28.9147 (  44.039% error) |          |          |****      |          |
2025:   74213.0000 vs ref   74180.1138: diff      32.8862 (  44.333% error) |          |          |****      |          |
2026:   82812.0000 vs ref   82775.3323: diff      36.6677 (  44.298% error) |          |          |****      |          |
2027:   91484.0000 vs ref   91443.3524: diff      40.6476 (  44.451% error) |          |          |****      |          |
2028:  100230.0000 vs ref  100184.7906: diff      45.2094 (  45.126% error) |          |          |****      |          |
2029:  109050.0000 vs ref  109000.2688: diff      49.7312 (  45.625% error) |          |          |****      |          |
2030:  126884.0000 vs ref  126865.7971: diff      18.2029 (  14.348% error) |          |          |*         |          |
2031:  144869.0000 vs ref  144882.6464: diff     -13.6464 (  -9.419% error) |          |          |          |          |
2032:  163006.0000 vs ref  163052.0984: diff     -46.0984 ( -28.272% error) |          |        **|          |          |
2033:  181297.0000 vs ref  181375.4456: diff     -78.4456 ( -43.250% error) |          |      ****|          |          |
2034:  199743.0000 vs ref  199853.9917: diff    -110.9917 ( -55.536% error) |          |     *****|          |          |
2035:  218345.0000 vs ref  218489.0510: diff    -144.0510 ( -65.931% error) |          |    ******|          |          |
2036:  238138.0000 vs ref  238290.4192: diff    -152.4192 ( -63.964% error) |          |    ******|          |          |
2037:  258098.0000 vs ref  258259.5051: diff    -161.5051 ( -62.536% error) |          |    ******|          |          |
2038:  278228.0000 vs ref  278397.7291: diff    -169.7291 ( -60.966% error) |          |    ******|          |          |
2039:  298528.0000 vs ref  298706.5239: diff    -178.5239 ( -59.766% error) |          |     *****|          |          |
2040:  319000.0000 vs ref  319187.3341: diff    -187.3341 ( -58.691% error) |          |     *****|          |          |
2041:  339646.0000 vs ref  339841.6168: diff    -195.6168 ( -57.561% error) |          |     *****|          |          |
2042:  360467.0000 vs ref  360670.8413: diff    -203.8413 ( -56.517% error) |          |     *****|          |          |
2043:  381464.0000 vs ref  381676.4894: diff    -212.4894 ( -55.673% error) |          |     *****|          |          |
2044:  402639.0000 vs ref  402860.0552: diff    -221.0552 ( -54.871% error) |          |     *****|          |          |
2045:  423993.0000 vs ref  424223.0459: diff    -230.0459 ( -54.228% error) |          |     *****|          |          |
2046:  445528.0000 vs ref  445766.9811: diff    -238.9811 ( -53.611% error) |          |     *****|          |          |
2047:  467246.0000 vs ref  467493.3934: diff    -247.3934 ( -52.919% error) |          |     *****|          |          |
2048:  489148.0000 vs ref  489403.8285: diff    -255.8285 ( -52.273% error) |          |     *****|          |          |
2049:  511236.0000 vs ref  511499.8449: diff    -263.8449 ( -51.583% error) |          |     *****|          |          |
2050:  533511.0000 vs ref  533783.0146: diff    -272.0146 ( -50.960% error) |          |     *****|          |          |
2051:  555975.0000 vs ref  556254.9227: diff    -279.9227 ( -50.323% error) |          |     *****|          |          |
2052:  578629.0000 vs ref  578917.1679: diff    -288.1679 ( -49.777% error) |          |      ****|          |          |
2053:  601475.0000 vs ref  601771.3623: diff    -296.3623 ( -49.248% error) |          |      ****|          |          |
2054:  624515.0000 vs ref  624819.1318: diff    -304.1318 ( -48.675% error) |          |      ****|          |          |
2055:  647750.0000 vs ref  648062.1158: diff    -312.1158 ( -48.161% error) |          |      ****|          |          |
2056:  671182.0000 vs ref  671501.9679: diff    -319.9679 ( -47.650% error) |          |      ****|          |          |
2057:  694812.0000 vs ref  695140.3556: diff    -328.3556 ( -47.236% error) |          |      ****|          |          |
2058:  718643.0000 vs ref  718978.9604: diff    -335.9604 ( -46.727% error) |          |      ****|          |          |
2059:  742675.0000 vs ref  743019.4782: diff    -344.4782 ( -46.362% error) |          |      ****|          |          |
2060:  766911.0000 vs ref  767263.6192: diff    -352.6192 ( -45.958% error) |          |      ****|          |          |
2061:  791353.0000 vs ref  791713.1080: diff    -360.1080 ( -45.485% error) |          |      ****|          |          |
2062:  816002.0000 vs ref  816369.6841: diff    -367.6841 ( -45.039% error) |          |      ****|          |          |
2063:  840860.0000 vs ref  841235.1013: diff    -375.1013 ( -44.589% error) |          |      ****|          |          |
2064:  865928.0000 vs ref  866311.1286: diff    -383.1286 ( -44.225% error) |          |      ****|          |          |
2065:  891209.0000 vs ref  891599.5498: diff    -390.5498 ( -43.803% error) |          |      ****|          |          |
2066:  916704.0000 vs ref  917102.1640: diff    -398.1640 ( -43.415% error) |          |      ****|          |          |
2067:  942415.0000 vs ref  942820.7854: diff    -405.7854 ( -43.040% error) |          |      ****|          |          |
2068:  968344.0000 vs ref  968757.2434: diff    -413.2434 ( -42.657% error) |          |      ****|          |          |
2069:  994493.0000 vs ref  994913.3833: diff    -420.3833 ( -42.253% error) |          |      ****|          |          |
2070: 1020863.0000 vs ref 1021291.0656: diff    -428.0656 ( -41.914% error) |          |      ****|          |          |

In essense..

(13, 7900), (6, 16800), (36, 17800)

I=0;X=0;Y=2016;
for (c:"\u4f0d\ua806\ub224") {
    for (I=0; I++ < (c&0xFF); Y++, X += (c >> 8) * 100) {
        print(Y + "	" + (X += X / 118));
    }
}

109 chars


I=0;X=0;Y=2016;
for (c:"\u4f0d\ua806\ub224")
    for (I=0; I++ < (c&0xFF); Y++, X += (c >> 8) * 100)
        print(Y + "     " + (X += X / 118));

105 chars


X=0;Y=16;
for (c:"\u4f1d\ua823\ub247")
    for (;Y < (c&0xFF); X += (c >> 8) * 100)
        print(2e3 + Y++ + "	" + (X += X / 118));

96 chars


X=0;Y=16;
for (c:"伝ꠣ뉇")
    for (;(c&255) > Y; X += (c >> 8) * 100, X += X / 118)
        print(2e3 + Y++ + "	" + X);

80 chars


X=0;Y=16;
for (c:"ỹ䇃䗏")
    for (;c%100 > Y; X += c/100*100, X += X / 118)
        print("20" + Y++ + "	" + X);

78 chars

Hic sunt dracones!


X=Y=0;
for (c:"㷀荁謇")
    for (;c % 8 * 6 + 13 > Y; X += c / 2, X += X / 118)
        print(2016 + Y++ + "	" + X);

72 chars


X=Y=0;
for (c:"ἠ䉁䘧")
    for (;c % 8 * 6 + 13 > Y; X += c + X / 118)
        print(2016 + Y++ + "	" + X);

67 chars


X=Y=0;
for (c:"ἢ䉃䘩")
    for (;c % 16 * 6 >= Y; X += c + X / 118)
        print(2016 + Y++ + "	" + X);

66 chars


ᗇ=ᐶ=0;
for (ᐷ:"ἢ䉃䘩")
    for (;ᐷ % 16 * 6 >= ᐶ; ᗇ += ᐷ + ᗇ / 118)
        print('ߠ' + ᐶ++ + "	" + ᗇ);

65 chars

But this is no good..


int X=0, Y=0;
foreach (char c in "ἢ䉃䘩")
    for (;c % 16 * 6 >= Y; X += c + X / 118)
        print(2016 + Y++ + "	" + X)
  

82 chars


int X, Y;
foreach (var c in "ἢ䉃䘩")
    for (;c % 16 * 6 >= Y; X += c + X/118)
        print($"20{Y+++16}	{X}")
  

80 chars


int ᗇ,ᐶ;
for (; ᐶ++ < 55; ᗇ += "Ἕ䈯䘐"[ᐶ>13?ᐶ>19?2:1:0] + ᗇ/118)
    print(2015+ᐶ+"	"+ᗇ)
  

71 chars


int ᗇ,ᐶ;
for (; ᐶ++ < 55; ᗇ += "Ἕ䈯䘐"[ᐶ>13?ᐶ>19?2:1:0] + ᗇ/'v')
    print('ߟ'+ᐶ+"	"+ᗇ)
  

70 chars


int ᗇ,ᐶ;
for (;ᐶ++ < 55; ᗇ += "Ἕ䈯䘐"[13%ᐶ/13 + 19%ᐶ/19] + ᗇ/'v')
     print('ߟ'+ᐶ+"	"+ᗇ)
  

70 chars (still...)


int ᗇ,ᐶ='ߟ';
for (; ᐶ++ < 'ࠖ'; ᗇ += "Ἕ䈯䘐䘐"['߬' % ᐶ + '߲' % ᐶ >> 10] + ᗇ/'v')
    print(ᐶ+"	"+ᗇ)

72 chars (worse!)


int ᗇ,ᐶ;
for (;ᐶ < 55; ᗇ += "Ἕ䈯䘢"[ᐶ++>18?2:ᐶ/14] + ᗇ/'v')
    print('ߠ'+ᐶ+"	"+ᗇ)

66 chars

Smaller!


16 71 crange
{
  save-c 2000 +
  "     " push-b new-line
  4 extract-array

  # (Y / 35 * 1024) + 8864
  push-c 35 / 1024 * 8864 +

  # Y > 28 ? last : 0
  push-c 28 gt *

  # x += y-cond
  push-b +

  # x += 7904
  7904 +

  # x += x / 118
  dup 118 / + pop-b
} map

unwords map1

49 chars


16 71 crange

m:
  save-c 2000 +
  "     " push-b new-line
  4 extract-array
  unwords

  # (Y / 35 * 1024) + 8864
  push-c 35 / 1024 * 8864 +

  # Y > 28 ? last : 0
  push-c 28 gt *

  # x += y-cond
  push-b +

  # x += 7904
  7904 +

  # x += x / 118
  dup 118 / + pop-b

46 chars


16 71 crange
{
  save-c
  1000 double +
  "\x09" push-b new-line

  1000
  # Y > 34 ? 1000 : 0
  34 push-c lt *
  # Y += 8900
  8900 +

  # Y > 28 ? last : 0
  28 push-c lt *
  # x += 7900
  7900 +

  # x += y-cond
  push-b +

  # x += x / 118
  dup 118 / + pop-b
} each

42 chars


16 71 crange

m:
  1000 double + show
  9 push-b show new-line

  1000
  # Y > 34 ? 1000 : 0
  @2 34 gt inc *

  # Y += 7900
  7900 +

  # Y > 28 ? last : 0
  @5 28 gt *

  # x += 7900
  @5 +

  # x += y-cond
  push-b +

  # x += x / 118
  dup 118 / +
  pop-b

39 chars


16 71 crange
empty-list  7900 + 13 *
empty-list 16800 +  6 * +
empty-list 17800 + 36 * +
zip

m:
  head
  1000 double +
  show
  9
  push-b show
  push-b @5 last +
  dup 118 / +
  pop-b
  new-line

49 chars (worse!)


 79 itemize 13 *
168 itemize  6 * +
178 itemize 36 * +

m:
  pop-c
  counter 2015 + show
  9
  push-b show
  new-line

  push-b
  push-c 100 *
  +
  dup 118 / +
  pop-b

41 chars (previous best: 39)


"\x4f\xa8\xb2"
"\x1a\x0c\x48" half m1
compress

m:
  pop-c
  counter 2015 + show
  9
  push-b show
  new-line

  push-b
  push-c 100 *
  +
  dup 118 / +
  pop-b

34 chars


"\x4f\xa8\xb2\x07\x1a\x0c\x48" half m1
compress

m:
  pop-c
  counter 2015 + show
  9
  push-b show
  new-line

  push-b
  push-c 100 *
  +
  dup 118 / +
  pop-b

33 chars (half!)

Questions?

ci@iversenit.dk