# Compute xkcd's Wrong Times Table

The 2020-05-29 xkcd comic showed us the numbers that Randall Munroe feels would be most likely to result from multiplication, other than the correct answers. The table does seem to have some sort of twisted logic to it.

For your convenience, the Wrong Times Table is reproduced here in selectable format:

+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|     | 1   | 2   | 3   | 4   | 5   | 6   | 7   | 8   | 9   | 10  |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| 1   | 0   | ½   | 4   | 5   | 6   | 7   | 8   | 9   | 10  | 9   |
| 2   | ½   | 8   | 5   | 6   | 12  | 14  | 12  | 18  | 19  | 22  |
| 3   | 4   | 5   | 10  | 16  | 13  | 12  | 24  | 32  | 21  | 33  |
| 4   | 5   | 6   | 16  | 32  | 25  | 25  | 29  | 36  | 28  | 48  |
| 5   | 6   | 12  | 13  | 25  | 50  | 24  | 40  | 45  | 40  | 60  |
| 6   | 7   | 14  | 12  | 25  | 24  | 32  | 48  | 50  | 72  | 72  |
| 7   | 8   | 12  | 24  | 29  | 40  | 48  | 42  | 54  | 60  | 84  |
| 8   | 9   | 18  | 32  | 36  | 45  | 50  | 54  | 48  | 74  | 56  |
| 9   | 10  | 19  | 21  | 28  | 40  | 72  | 60  | 74  | 72  | 81  |
| 10  | 9   | 22  | 33  | 48  | 60  | 72  | 84  | 56  | 81  | 110 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+


0 ½ 4 5 6 7 8 9 10 9 ½ 8 5 6 12 14 12 18 19 22 4 5 10 16 13 12 24 32 21 33 5 6 16 32 25 25 29 36 28 48 6 12 13 25 50 24 40 45 40 60 7 14 12 25 24 32 48 50 72 72 8 12 24 29 40 48 42 54 60 84 9 18 32 36 45 50 54 48 74 56 10 19 21 28 40 72 60 74 72 81 9 22 33 48 60 72 84 56 81 110


# Challenge

Your goal is to write a program or function that accepts two numbers as input and returns the corresponding value of the Wrong Times Table as output.

• The inputs and output can be in any format and data type, as long as it is self-evidently clear which number a given value represents. So representing ½ as the floating point number 0.5 or the string "1/2" is fine, but representing it as -1 is not.
• The inputs can be assumed to be integers in the range 1 to 10 inclusive.
• Standard rules and loophole restrictions apply. The shortest code in bytes wins.

Input:

5
3

Output:

13

# Some possible avenues for golfing

• The table is symmetric across the diagonal.
• There are some patterns in the numbers, e.g. f(1, n) = n + 1 for 3 ≤ n ≤ 9.
• The values in the table are usually numerically close to the actual multiplication table, so you could store the differences instead.
• The explain xkcd wiki page for this comic has a table showing how each number might have been derived. It may take fewer bits to store these offsets than to store the output numbers directly.
• He's providing it for the convenience of people writing solutions, for verification and for easy compression purposes. – Unrelated String May 30 '20 at 1:37
• I'm confused by your "flattened ASCII version without headers:" as ½ isn't an ASCII character. Did you mean "1/2" instead? – Abigail May 30 '20 at 9:51
• @Arnauld Yeah, I don't know what's going on there.... The wiki page for this comic had a table showing, for each entry, a formula in terms of the row and column index that evaluates to the output value. For example, almost half the entries are of the form i*(j+1) or i*(j-1) with i ≤ j. I was thinking you could just store a marker for these entries to make the table compress better, if you could make the corresponding evaluation code small enough in a golfing language. – Aaron Rotenberg May 30 '20 at 13:38
• When I grow up, I'm going to send my children to the primary school Randall Munroe has been in. – user92069 May 31 '20 at 0:59
• @Arnauld Explain XKCD seems to be back up now. I don't know if there are few enough distinct formulas to make it worthwhile though. – Neil Jun 2 '20 at 10:42

# Python 3, 119 ... 110 105 bytes

-14 bytes thanks to @xnor

Takes as input an array $$\ a\$$ consisting of the two integers. Outputs the product of the two numbers based on the Wrong Times Table. For the case [1, 2] or [2, 1], it outputs .5.

lambda a:b' \0\n \r2 (0*	 $-260\n (H<JH !0<HT8Qn'[max(a)*~-max(a)//2+min(a)]%126.5  Try it online! ## Explanation We use a compressed string which stores the answers as ASCII values. And since multiplication is commutative, it doesn't matter in which order the two numbers appear, effectively reducing the compression size by a half. For the .5 edge case, we assign the character with the ASCII value 127 to it. Then we apply modulo 126.5 to it. This results in 127 % 126.5 returning .5, but all the other values stay the same. • Looks like you can just do a!=[1,2] in place of sum(a)!=3 since a is sorted at that point. There might be a still shorter way. – xnor May 30 '20 at 2:35 • Actually maybe a shorter way to handle 0.5 would be to assign some large byte like 127 to [1,2], then take the final result modulo 126.5. Also tempting is or.5 but there's a zero output already that might take too long to deal with. – xnor May 30 '20 at 2:41 • @xnor That's a really nice idea, thanks! – dingledooper May 30 '20 at 2:53 • Turns out shorter to do the min and max explicitly: TIO – xnor May 30 '20 at 11:50 • Hmm, (2*max(a)-1)**2//8 is the same length: TIO – xnor May 30 '20 at 11:51 # Charcoal, 86 bytes §⪪§⪪”#｜D⟦ⅈＱ\Ｓ4,▷-³◨⟦v≔[Q!ξ№﹪⪪wQＣ.≡r¿I↗⎇B⁸⟧“¿*⪫Y<h\/Ｅ¿M‴$ε¬{a⸿Ｒ⁷⊙ZＮU{Ｕⅈ⪪mδp^｜⎇υＯ”¶⌈θ ⌊θ


Try it online! Takes input as a tuple. Explanation:

    ”...”       Compressed string of rotated lower left half of table
⪪     ¶      Split on newlines
§       ⌈θ    Cyclically indexed by maximum of both inputs
⪪              Split on spaces
§            ⌊θ Cyclically indexed by minimum of both inputs
Implicitly print


Because Charcoal is 0-indexed and the input is 1-indexed I've rotated the diagonal of the lower left half of the table to the left of the first column and then rotated the last row to above the first row so that the cyclic indexing picks up the desired result.

# Jelly,  75  71 bytes

“µẎḂƬḌƑ®ṢṄḶ+/ḤƇ’BT3+.;Żṃ@“¦¦SȤSḢ⁺ḥȧ⁹ .rOƘ,ṃȯJƓṄƭ3ƝṁṫY-ŻḂƇS|~Ƭø’
ṀḶS+Ṃị¢


A monadic Link accepting a pair of integers in $$\[1..10]\$$ which yields a number.

Try it online!

### How?

“...’BT3+.;Żṃ@“...’ - Link 1, get lower left of table as a flat list: no arguments
“...’               - a large number in base 250
B              - convert to binary
T             - truthy indices
3+           - add three to them all -> all distinct values except 0 and 0.5)
.;         - prepend a 0.5
Ż        - prepend a zero -> all 37 distinct values
“...’ - a large number in base 250
ṃ@      - convert the large number to base 37 using the values as the digits
-> [0, 0.5, 8, 4, 5, 10, 5, 6, 16, 32, 6, 12, 13, 25, 50, 7, 14, 12, 25, 24, 32, 8, 12, 24, 29, 40, 48, 42, 9, 18, 32, 36, 45, 50, 54, 48, 10, 19, 21, 28, 40, 72, 60, 74, 72, 9, 22, 33, 48, 60, 72, 84, 56, 81, 110]

ṀḶS+Ṃị¢ - Link, get answer: list of two integers in [1..10], [a,b]
Ṁ       - maximum ([a,b])
Ḷ      - lowered range -> [0,1,...,max(a,b)-1]
S     - sum these up
Ṃ   - minimum ([a,b])
¢ - call last Link (2) as a nilad -> lower left of table as a flat list
ị  - index into


# 05AB1E, 100 bytes

-2 thanks to Kevin Cruijssen.

•k?-…ÚêQïBJÿ}Å0ß7E'ûcŒa’н
[α¡¥jεĆ3fΣòZεgǝ/ζân[Qx¯#g)zòš¤¥Ägq)†c³±!Ãæwª“‹í«“ε®™â©₂ÿQ•ƵAв1;š¬9ǝ0šs<Jè


Try it online!

# 05AB1E, 102 bytes

The number 2 never appears in the multiplication table, so I used it to compress the list of the numbers.

•AjĆмÁмyÌÁÅÿ‰™ªŸ∞mÇ,—.¿b!:ý₆¥p¶ço₃w2å,3‚ĆžáààÄd±íŠH¢Xζ±-ε₁ÎZ₆ºλΓm.Óc9˜}‘UÔœŸā£ƒn¨£T•111в2¸1;¸‡0šs<Jè


Try it online!

## Explanation

•AjĆмÁмyÌÁÅÿ‰™ªŸ∞mÇ,—.¿b!:ý₆¥p¶ço₃w2å,3‚ĆžáààÄd±íŠH¢Xζ±-ε₁ÎZ₆ºλΓm.Óc9˜}‘UÔœŸā£ƒn¨£T•111в

The huge compressed table

2¸1;¸‡ Translate all 2's into 0.5's
0š     Prepend a 0 (which is removed during base conversion)
s      Swap up the list of indices.
<      Decrement both indices.
J      Join these indices into a single number.
è      Index into the table.
$$$$

• ... why did you answer three times instead of editing your single answer until it was correct? – Neil May 30 '20 at 10:39
• 111 can be ƵA (or 7b) for -1. Also, if you can use 1;š¬9ǝ instead of 2¸1;¸‡ (same byte-count), the compressed integer can be 1 byte smaller by removing the leading 2 of the initially compressed list: 100 bytes. – Kevin Cruijssen Jun 2 '20 at 7:06

# JavaScript, 114 113 bytes

Input as f(1)(2). Port of @dingledooper's Python 3 answer.

a=>b=> \0
 \r2 (0*	 \$-260\n(H<JH	!0<HT8Qn.charCodeAt((M=a>b?a:b)*~-M/2+(a<b?a:b))%126.5


Try it online!

• 109 bytes – Arnauld May 30 '20 at 10:38
• or 106 in Node – Arnauld May 30 '20 at 10:43