26
\$\begingroup\$

The Cheela (from the book Dragon's Egg by Robert L. Forward) are creatures that live on the surface of a neutron star. Their body is flat and circular with twelve eyes on the perimeter, so they naturally use a base-12 numbering system.

Among the Cheela, care of the hatchlings and education of the young are tasks carried out by the Old Ones. Since young Cheela need to be taught how to multiply, the Old Ones could use a multiplication table.

Your task is to produce a 12x12 multiplication table in base 12, like the following. Uppercase letters A and B are used for digits corresponding to decimal 10 and 11 respectively.

  1   2   3   4   5   6   7   8   9   A   B  10 
  2   4   6   8   A  10  12  14  16  18  1A  20 
  3   6   9  10  13  16  19  20  23  26  29  30 
  4   8  10  14  18  20  24  28  30  34  38  40 
  5   A  13  18  21  26  2B  34  39  42  47  50 
  6  10  16  20  26  30  36  40  46  50  56  60 
  7  12  19  24  2B  36  41  48  53  5A  65  70 
  8  14  20  28  34  40  48  54  60  68  74  80 
  9  16  23  30  39  46  53  60  69  76  83  90 
  A  18  26  34  42  50  5A  68  76  84  92  A0 
  B  1A  29  38  47  56  65  74  83  92  A1  B0 
 10  20  30  40  50  60  70  80  90  A0  B0 100

The output shoud be printed on screen. The format should be as follows:

  1. Numbers should be aligned to the right within each column.
  2. Leading spaces before the first column, trailing spaces after the last column, or a trailing new line after the last row are allowed.
  3. Separation between columns can be one space (as shown above) or more than one space, but the number of spaces should be consistent between columns. To measure column separation, consider that displayed numbers include any leading spaces that may have been necessary fo fulfill requirement 1 (so each number occupies three characters, the first of which may be spaces). For example, the table with two-space separation would be as follows:

      1    2    3    4    5    6    7    8    9    A    B   10 
      2    4    6    8    A   10   12   14   16   18   1A   20 
      3    6    9   10   13   16   19   20   23   26   29   30 
      4    8   10   14   18   20   24   28   30   34   38   40 
      5    A   13   18   21   26   2B   34   39   42   47   50 
      6   10   16   20   26   30   36   40   46   50   56   60 
      7   12   19   24   2B   36   41   48   53   5A   65   70 
      8   14   20   28   34   40   48   54   60   68   74   80 
      9   16   23   30   39   46   53   60   69   76   83   90 
      A   18   26   34   42   50   5A   68   76   84   92   A0 
      B   1A   29   38   47   56   65   74   83   92   A1   B0 
     10   20   30   40   50   60   70   80   90   A0   B0  100
    

Computer storage on a neutron star is really expensive, so your code should use as few bytes as possible.

Extended challenge and bonus

Ideally your code should be reused in other parts of the universe, where other numbering systems may be in use. To that end, the challenge is optionally extended as follows: Your code accepts a number N as input and generates an NxN multiplication table in base N, with the above format.

Input may be from keyboard or as a function argument. The program or function should work for 2N36, using as digits the first N characters of the sequence 0, 1, ..., 9, A, B, ..., Z (uppercase letters)

This extended challenge is optional. If you follow this route, take 20% off your byte count (no need to round to an integer number).

\$\endgroup\$
  • \$\begingroup\$ Nice one Luis! =) I wish I had the time to come up with a MATLAB solution, but I'm busy measuring Christmas gift dimensions... \$\endgroup\$ – Stewie Griffin Dec 20 '15 at 18:23
  • 6
    \$\begingroup\$ Good luck with those spherical hats! :-P \$\endgroup\$ – Luis Mendo Dec 20 '15 at 18:26
  • 5
    \$\begingroup\$ Because they have twelve eyes, they naturally use a base-12 numbering system. Well, naturally. That's why we use binary, after all... ;-) \$\endgroup\$ – Tim Pederick Dec 21 '15 at 13:34
  • 2
    \$\begingroup\$ @TimPederick Good point :-D To clarify: the body of a Cheela is circular, they can reshape limbs as needed... having twelve eyes is numerically the most distinct feature of their bodies. I've updated the question, thanks! \$\endgroup\$ – Luis Mendo Dec 21 '15 at 13:44
  • 1
    \$\begingroup\$ @LuisMendo very nice novel, the one you quote. Starquake isn't bad either. \$\endgroup\$ – lstefano Jun 28 '16 at 16:10

17 Answers 17

14
\$\begingroup\$

Pyth, 27 * 0.8 = 21.6

VSQsm.[\ 4jkXj*dNQrT99rG1SQ

Try it online: Demonstration

Explanation:

VSQsm.[\ 4jkXj*dNQrT99rG1SQ   implicit: Q = input number
VSQ                           for N in [1, 2, ..., Q]:
    m                    SQ      map each number d in [1, 2, ..., Q] to:
              *dN                   N * d
             j   Q                  in base Q
            X     rT99rG1           replace the numbers [10, 11, ..., 98] with "A...Z"
          jk                        join to a string
     .[\ 4                          prepend spaces, so that the string has a length of 4
   s                             join all strings and print
\$\endgroup\$
11
\$\begingroup\$

CJam, 33 * 0.8 = 26.4 bytes

ri:C,:)_ff{*Cb{_9>{'7+}&}%4Se[}N*

Test it here.

This uses the minimum required separation.

Explanation

ri:C        e# Read input, convert to integer, store in C.
,:)         e# Get range [1 2 ... C].
_ff{        e# 2D-map over all repeated pairs from that range...
  *Cb       e#   Multiply, convert to base C.
  {         e#   Map over the digits...
    _9>     e#     Check if the digit is greater than 9.
    {'7+}&  e#     If so, add the digit to the character "7", to get "A" to "Z".
  }%
  4Se[      e#   Pad the digits with spaces from the left, to 4 elements.
}
N*          e# Join with linefeeds.

Table for input 22 (the largest that fits in the post without a horizontal scrollbar):

   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F   G   H   I   J   K   L  10
   2   4   6   8   A   C   E   G   I   K  10  12  14  16  18  1A  1C  1E  1G  1I  1K  20
   3   6   9   C   F   I   L  12  15  18  1B  1E  1H  1K  21  24  27  2A  2D  2G  2J  30
   4   8   C   G   K  12  16  1A  1E  1I  20  24  28  2C  2G  2K  32  36  3A  3E  3I  40
   5   A   F   K  13  18  1D  1I  21  26  2B  2G  2L  34  39  3E  3J  42  47  4C  4H  50
   6   C   I  12  18  1E  1K  24  2A  2G  30  36  3C  3I  42  48  4E  4K  54  5A  5G  60
   7   E   L  16  1D  1K  25  2C  2J  34  3B  3I  43  4A  4H  52  59  5G  61  68  6F  70
   8   G  12  1A  1I  24  2C  2K  36  3E  40  48  4G  52  5A  5I  64  6C  6K  76  7E  80
   9   I  15  1E  21  2A  2J  36  3F  42  4B  4K  57  5G  63  6C  6L  78  7H  84  8D  90
   A   K  18  1I  26  2G  34  3E  42  4C  50  5A  5K  68  6I  76  7G  84  8E  92  9C  A0
   B  10  1B  20  2B  30  3B  40  4B  50  5B  60  6B  70  7B  80  8B  90  9B  A0  AB  B0
   C  12  1E  24  2G  36  3I  48  4K  5A  60  6C  72  7E  84  8G  96  9I  A8  AK  BA  C0
   D  14  1H  28  2L  3C  43  4G  57  5K  6B  72  7F  86  8J  9A  A1  AE  B5  BI  C9  D0
   E  16  1K  2C  34  3I  4A  52  5G  68  70  7E  86  8K  9C  A4  AI  BA  C2  CG  D8  E0
   F  18  21  2G  39  42  4H  5A  63  6I  7B  84  8J  9C  A5  AK  BD  C6  CL  DE  E7  F0
   G  1A  24  2K  3E  48  52  5I  6C  76  80  8G  9A  A4  AK  BE  C8  D2  DI  EC  F6  G0
   H  1C  27  32  3J  4E  59  64  6L  7G  8B  96  A1  AI  BD  C8  D3  DK  EF  FA  G5  H0
   I  1E  2A  36  42  4K  5G  6C  78  84  90  9I  AE  BA  C6  D2  DK  EG  FC  G8  H4  I0
   J  1G  2D  3A  47  54  61  6K  7H  8E  9B  A8  B5  C2  CL  DI  EF  FC  G9  H6  I3  J0
   K  1I  2G  3E  4C  5A  68  76  84  92  A0  AK  BI  CG  DE  EC  FA  G8  H6  I4  J2  K0
   L  1K  2J  3I  4H  5G  6F  7E  8D  9C  AB  BA  C9  D8  E7  F6  G5  H4  I3  J2  K1  L0
  10  20  30  40  50  60  70  80  90  A0  B0  C0  D0  E0  F0  G0  H0  I0  J0  K0  L0 100
\$\endgroup\$
8
\$\begingroup\$

MATL, 42*.8 = 33.6

Disclaimer

Since the creator of the language and the author of the challenge are the same, this answer is not eligible for winning.

For a discussion on whether this restriction is necessary or not, see this meta question.

Code

iXK:t!*Y)KYAZ{'(?<=^0*)0'32cYXZc32hK4*[]e!

This uses the minimum separation.

Example

Octal multiplication table

>> matl
 > iXK:t!*Y)KYAZ{'(?<=^0*)0'32cYXZc32chK4*[]e!
 > 
> 8
  1   2   3   4   5   6   7  10 
  2   4   6  10  12  14  16  20 
  3   6  11  14  17  22  25  30 
  4  10  14  20  24  30  34  40 
  5  12  17  24  31  36  43  50 
  6  14  22  30  36  44  52  60 
  7  16  25  34  43  52  61  70 
 10  20  30  40  50  60  70 100 

Explanation

i              % input number, say n
XK             % copy to clipboard K
:              % vector 1, 2, ... n
t!*            % generate table: duplicate, transpose and multiply with broadcasting
Y)             % linearize into column array
KYA            % paste n from clipboard K. Convert to that base
Z{             % cell array of rows from array
'(?<=^0*)0'    % string literal for regexp replacement: find leading zeros
32c            % space character (for regexp replacement)
YX             % regexp replacement
Zc             % join cell array of strings into single string   
32             % code for space character. Conversion to char happens automatically
h              % concatenate horizontally
K4*[]e!        % paste n and multiply by 4. Reshape into 2D char array with 4*n columns

Edit: Try it online!

To run in the online compiler (as of February 19, 2016), change Y) to X:, and remove []. This is to adapt to changes that have been made to the language since this challenge was posted.

\$\endgroup\$
  • \$\begingroup\$ "Since the creator of the language and the author of the challenge are the same, this answer is not eligible for winning." I wasn't aware of this restriction. Is this self-imposed or did you find a relevant meta consensus? \$\endgroup\$ – Alex A. Dec 20 '15 at 19:18
  • 1
    \$\begingroup\$ @AlexA. I self-imposed it. I suspected there probably was some kind of agreement regarding that. From your commnent I see there isn't there any? My point is: if you design a language and then post a challenge, you are probably at an advantageous position. What's usually done about that? Not any restriction? \$\endgroup\$ – Luis Mendo Dec 20 '15 at 19:21
  • \$\begingroup\$ I would think you aren't necessarily at an advantage so long as you don't plan a challenge specifically as a use case for a built-in in your language. I don't know of any such consensus offhand, so I recommend asking on meta. \$\endgroup\$ – Alex A. Dec 20 '15 at 19:24
  • \$\begingroup\$ @AlexA. Good idea! Done \$\endgroup\$ – Luis Mendo Dec 20 '15 at 19:35
  • \$\begingroup\$ @AlexA. If you feel like doing it, maybe add your suggestion as an answer there? \$\endgroup\$ – Luis Mendo Dec 20 '15 at 19:40
5
\$\begingroup\$

Bash + BSD utilities, 36

echo Co{1..12}d{1..12}*p|dc|rs -j 12

Works out-of-the-box on OS X. rs may need to be installed on Linux systems.

  • Bash expands Co{1..12}d{1..12}*p to Co1d1*p Co1d2*p Co1d3*p ... Co1d12*p ... Co12d12*p.
  • This is a dc expression that generates the required terms. Co sets output base to 12. d is used as a separator between numbers instead of a space, so no escape is required in the brace expansion. d actually duplicates the top of stack, but this is effectively ignored and discarded.
  • The output from dc is a single space-separated line. rs reshapes this to a 12x12 array. -j right-justifies each term.
\$\endgroup\$
4
\$\begingroup\$

Pyth, 36 bytes

Km+1dUJ12rjbmjkm.[\ 4j""m.Hbj*dkJKK1

Try it here.

\$\endgroup\$
  • \$\begingroup\$ You can replace Km+1dUJ12 with KSJ12. S creates the range [1, 2, ..., 12]. You can replace both j"" and jk with s, since your joining strings. And another byte: Change rjbm...K1 to jmr...1K. With this changes you get 28 bytes: KSJ12jmrsm.[\ 4sm.Hbj*dkJK1K \$\endgroup\$ – Jakube Dec 20 '15 at 18:12
4
\$\begingroup\$

Python, 153 147 132 bytes * 0.8 = 105.6

def p(b):
 f=lambda n:(n>=b and f(n/b)or'')+chr((48,55)[n%b>9]+n%b)
 for i in range(b*b):print'%4s\n'[:3+(~i%b<1)]%f(~(i%b)*~(i/b)),

Down to 132 bytes thanks to the advice of Tim Pederick! :)

\$\endgroup\$
  • \$\begingroup\$ Upvoted, because the more I golf my answer, the more it starts to look like yours! \$\endgroup\$ – Tim Pederick Dec 21 '15 at 6:07
  • \$\begingroup\$ Some possible improvements: Use %-formatting instead of rjust ('%4s'%f(...)). See whether printing each value with print ..., (and then one print for the newline) is shorter than join. If so, try collapsing the loops. \$\endgroup\$ – Tim Pederick Dec 21 '15 at 12:06
  • \$\begingroup\$ Thanks Tim, I tried collapsing the loops (I didn't know this trick). I'm not sure it makes me gain many bytes if any but it's pretty cool :) \$\endgroup\$ – basile-henry Dec 21 '15 at 12:33
  • \$\begingroup\$ I see you switched to a ternary form (condition and A or B) inside function f, using n>=b. I did that until I realised that it was no shorter than what I had before, n//b... but you're using Python 2! You can save a byte with n/b. \$\endgroup\$ – Tim Pederick Dec 21 '15 at 12:39
  • \$\begingroup\$ Yes that's the reason I used this part of your code exploiting python 2 to save one more byte :) \$\endgroup\$ – basile-henry Dec 21 '15 at 12:40
4
\$\begingroup\$

CJam, 38 33 32 38 * (.8) = 30.4 bytes

qi:D,:):L{Lf*{Db{_9>{55+c}&}%4Se[}%N}%

Try it here.

(Looks pretty similar to Martin's now.)

qi:D,:):L          e# Generate list of [1...input]
{Lf*               e# Take each number in that list and multiply it by the same list ([[1,2,3,..,input][2,4,6,...,input],...})
{Db{_9>{55+c}&}%   e# Convert each product to base input. If a digit value is >= 10 add 55 and convert to char, to make it a letter.
4Se[}%N}%          e# Pad each number with spaces to length 4. Put a newline after each row.
\$\endgroup\$
3
\$\begingroup\$

Perl 6, 60 bytes -20% = 48 bytes

{.put for (1..$_ X*1..$_)».base($_)».fmt('%3s').rotor($_)} # 60-20% = 48
#          ^-----------^ produce a list of two cross multiplied lists
#                        ^--------^ convert each to base N
#          format each to 3 spaces ^----------^
#         split the list into N element chunks ^--------^
#^-------^ print each of those on their own line with spaces between elements

( This is almost exactly how I would write it even if I wasn't trying to get it as short as I could )

Usage:

{...}(2)
  1  10
 10 100
my &code = {...}
code 2;
  1  10
 10 100
{...}(12);
  1   2   3   4   5   6   7   8   9   A   B  10
  2   4   6   8   A  10  12  14  16  18  1A  20
  3   6   9  10  13  16  19  20  23  26  29  30
  4   8  10  14  18  20  24  28  30  34  38  40
  5   A  13  18  21  26  2B  34  39  42  47  50
  6  10  16  20  26  30  36  40  46  50  56  60
  7  12  19  24  2B  36  41  48  53  5A  65  70
  8  14  20  28  34  40  48  54  60  68  74  80
  9  16  23  30  39  46  53  60  69  76  83  90
  A  18  26  34  42  50  5A  68  76  84  92  A0
  B  1A  29  38  47  56  65  74  83  92  A1  B0
 10  20  30  40  50  60  70  80  90  A0  B0 100
{...}(18);
  1   2   3   4   5   6   7   8   9   A   B   C   D   E   F   G   H  10
  2   4   6   8   A   C   E   G  10  12  14  16  18  1A  1C  1E  1G  20
  3   6   9   C   F  10  13  16  19  1C  1F  20  23  26  29  2C  2F  30
  4   8   C   G  12  16  1A  1E  20  24  28  2C  2G  32  36  3A  3E  40
  5   A   F  12  17  1C  1H  24  29  2E  31  36  3B  3G  43  48  4D  50
  6   C  10  16  1C  20  26  2C  30  36  3C  40  46  4C  50  56  5C  60
  7   E  13  1A  1H  26  2D  32  39  3G  45  4C  51  58  5F  64  6B  70
  8   G  16  1E  24  2C  32  3A  40  48  4G  56  5E  64  6C  72  7A  80
  9  10  19  20  29  30  39  40  49  50  59  60  69  70  79  80  89  90
  A  12  1C  24  2E  36  3G  48  50  5A  62  6C  74  7E  86  8G  98  A0
  B  14  1F  28  31  3C  45  4G  59  62  6D  76  7H  8A  93  9E  A7  B0
  C  16  20  2C  36  40  4C  56  60  6C  76  80  8C  96  A0  AC  B6  C0
  D  18  23  2G  3B  46  51  5E  69  74  7H  8C  97  A2  AF  BA  C5  D0
  E  1A  26  32  3G  4C  58  64  70  7E  8A  96  A2  AG  BC  C8  D4  E0
  F  1C  29  36  43  50  5F  6C  79  86  93  A0  AF  BC  C9  D6  E3  F0
  G  1E  2C  3A  48  56  64  72  80  8G  9E  AC  BA  C8  D6  E4  F2  G0
  H  1G  2F  3E  4D  5C  6B  7A  89  98  A7  B6  C5  D4  E3  F2  G1  H0
 10  20  30  40  50  60  70  80  90  A0  B0  C0  D0  E0  F0  G0  H0 100
\$\endgroup\$
  • \$\begingroup\$ Not an expert, but is the space between 'for' and '(' required? Gotta clip the spaces where possible. \$\endgroup\$ – J_F_B_M Dec 20 '15 at 20:37
  • \$\begingroup\$ @J_F_B_M I always try removing spaces first. So if there is a space it is required. If I did remove the space it for sure wouldn't even compile as it would treat for( as the beginning of calling a subroutine named for instead of the modifier for loop construct. Which would cause a compilation error. \$\endgroup\$ – Brad Gilbert b2gills Dec 20 '15 at 23:03
  • \$\begingroup\$ Learned something. Thank you. \$\endgroup\$ – J_F_B_M Dec 20 '15 at 23:19
3
\$\begingroup\$

JavaScript (ES6) 84 (105-20%)

The obvious way, to begin with.

n=>{for(o=i=``;i++<n;o+=`
`)for(j=0;j++<n;)o+=(`   `+(i*j).toString(n)).slice(-4).toUpperCase();alert(o)}

Notes

  • It's a pity js toString produce lowercase letters
  • alert is not the best way to output the table, but it's the shorter, as there is an explicit request to "display on screen"
  • Just returning the value would be a couple bytes shorter.

Less golfed

n=>{
  for(o='', i=0; i++<n; o+='\n')
    for(j=0;j++<n;)
       o+=('   '+(i*j).toString(n)).slice(-4).toUpperCase()
  alert(o)
}
\$\endgroup\$
3
\$\begingroup\$

Python 3, 126 - 20% = 100.8 bytes

The outer function, t, is the one that actually prints the multiplication table. The inner function, i, does the conversion of a number to a base from 2 to 36.

def t(b):
 i=lambda n:(n>=b and i(n//b)or'')+chr(n%b+[48,55][n%b>9]);R=range(b)
 for r in R:print(*('%3s'%i(~r*~c)for c in R))

Hat tip to Boomerang for their solution, and for a golfing tip. I avoided copying anything from Boomerang's solution, but I did allow myself glances at it to see where I could trim more out. And even before that, I found that the more I golfed it, the more mine started to look like Boomerang's!

\$\endgroup\$
  • \$\begingroup\$ Nice solution! :) And you get a better score than me! I like the >9 instead of my <10. I'm not too familiar with python3 and starred expressions (I had to look that up). I love your ~ trick, I need to start using that! \$\endgroup\$ – basile-henry Dec 21 '15 at 10:45
  • \$\begingroup\$ I tested your solution a bit and it looks like i doesn't return more than two base n digits. For example if you do print(i(15,12),i(120,12),i(144,12),i(150,12)) your code returns 13 A0 00 06 instead of 13 A0 100 106. Unfortunately the task requires to print one 3 digit base n number (100). It shouldn't be too difficult to fix but it might add a few bytes... \$\endgroup\$ – basile-henry Dec 21 '15 at 11:02
  • \$\begingroup\$ @Boomerang: <scratches head> I think I must've broken something, then... because it was working before! The issue appears to be that it won't give a leading 1... oh, wait, I know what the problem is. It should be n>=b, not n>b. \$\endgroup\$ – Tim Pederick Dec 21 '15 at 11:40
  • \$\begingroup\$ I found another trick to make the code smaller: define i within t(b) so you can remove the second argument in i! Like this: def t(b): i=lambda n:(n>=b and i(n//b)or'')+chr(n%b+[48,55][n%b>9]) R=range(b) for r in R:print(*('%3s'%i(~r*~c)for c in R)) I'd like to do that in my solution but now both our solutions are pretty close, might as well improve the better one ^^ \$\endgroup\$ – basile-henry Dec 21 '15 at 11:53
  • \$\begingroup\$ @Boomerang: Hey, yours was first, and I think Python 2 offers enough shortcuts that you could still overtake me. But thanks for the help! \$\endgroup\$ – Tim Pederick Dec 21 '15 at 11:59
3
\$\begingroup\$

Javascript (ES6) 96.8 93.6 Bytes (20% of 117)

n=>{b='';for(i=0;i++<n;b+=`\n`)for(j=0;j++<n;)a=(i*j).toString(n).toUpperCase(),b+=' '.repeat(4-a.length)+a;alert(b)}

Explanation

n=>
    {                                     
      b='';                                    //clear table var at each run
      for(i=0;i++<n;b+=`\n`)                   //iterate through rows
        for(j=0;j++<n;)                        //iterate through cols
          a=(i*j).toString(n).toUpperCase(),   //get desired number
          b+=' '.repeat(4-a.length)+a";        //pad to right
    alert(b)                                   //display result
}

-saved 4 bytes thanks to @edc65

\$\endgroup\$
  • 1
    \$\begingroup\$ Simply using {} and alert(b) with no eval is shorter. And at least, avoid variable a, it's useless b+=' '.repeat(4-a.length)+(i*j).toString(n).toUpperCase() \$\endgroup\$ – edc65 Dec 21 '15 at 9:47
  • \$\begingroup\$ Thanks 😊 I didn't see the need to display it so for me eval() was originally shorter than returning the value. @edc65 however, if I avoid a how do you then compute ...repeat(4-a.length)...? \$\endgroup\$ – Aᴄʜᴇʀᴏɴғᴀɪʟ Dec 22 '15 at 5:57
  • \$\begingroup\$ Ugh sorry you're right about a. +1 as is \$\endgroup\$ – edc65 Dec 22 '15 at 7:38
2
\$\begingroup\$

MATLAB, 111*0.8=88.8 110*0.8=88 bytes

My debut here:

@(N)disp(reshape(strrep(strrep([' ',strjoin(cellstr(dec2base([1:N]'*[1:N],N)))],' 0','  '),' 0','  '),4*N,N)')

Explanation:

[1:N]'*[1:N] make multiplication table in base 10

dec2base([1:N]'*[1:N],N) convert to base 12. The output is char array with leading 0-s

strjoin(cellstr(dec2base(___))) convert to cell and back to char joining strings with space yielding 1x575 string

[' ',strjoin(___)] append space to have 576 elements

strrep(___,' 0',' ') remove one leading zero. We do it twice because we have strings with two leading zeros

reshape(___,4*N,N)' convert 1x576 char array into 48x12 char array

disp(___) display the result without ans =

Output:

 1   2   3   4   5   6   7   8   9   A   B  10
 2   4   6   8   A  10  12  14  16  18  1A  20
 3   6   9  10  13  16  19  20  23  26  29  30
 4   8  10  14  18  20  24  28  30  34  38  40
 5   A  13  18  21  26  2B  34  39  42  47  50
 6  10  16  20  26  30  36  40  46  50  56  60
 7  12  19  24  2B  36  41  48  53  5A  65  70
 8  14  20  28  34  40  48  54  60  68  74  80
 9  16  23  30  39  46  53  60  69  76  83  90
 A  18  26  34  42  50  5A  68  76  84  92  A0
 B  1A  29  38  47  56  65  74  83  92  A1  B0
10  20  30  40  50  60  70  80  90  A0  B0 100 

If we don't count statement N=12;, 5*.8=4 bytes are saved. Also, if ans = output is tolerated, then we can remove disp() saving another 6*0.8=4.8 bytes. Of course, there may be other ways to save bytes :)

\$\endgroup\$
  • \$\begingroup\$ In general, ans output is tolerated if the output is a function argument. But in this case the challenge says "output should be printed on screen", so ans is not allowed. Also, N should be taken as an input in the extended challenge. You can solve that using an anonymous function: @(n)disp(reshape(strrep(strrep([' ',strjoin(cellstr(dec2base([1:N]'*[1:N],N)))],' 0',' '),' 0',' '),4*N,N)'), which you would call using ans(12) \$\endgroup\$ – Luis Mendo Dec 21 '15 at 18:11
  • 1
    \$\begingroup\$ Oh and welcome to the site! :-) \$\endgroup\$ – Luis Mendo Dec 21 '15 at 18:12
  • \$\begingroup\$ @LuisMendo thanks! I'll edit my answer with @(N) notation \$\endgroup\$ – brainkz Dec 21 '15 at 18:24
2
\$\begingroup\$

Python 3: 166 161 152 - 20% = 121.6 bytes

I know it's inferior to the existing Python answers but I figured to give it a shot. It's my first time posting on this site…

def t(b):
 r=range(1,b+1);f=lambda x:x and f(x//b)+chr((55,48)[x%b>9]+x%b)or''
 print('\n'.join(''.join(B)for B in(('%4s'%f(i*j)for j in r)for i in r)))
\$\endgroup\$
  • \$\begingroup\$ There are 3 closing parenthesis and 2 numeric literals followed by spaces. Those spaces are unnecessary. Otherwise nice first try. BTW, Tips for golfing in Python is a nice reading. \$\endgroup\$ – manatwork Dec 22 '15 at 15:12
  • \$\begingroup\$ Welcome to PPCG.SE, even if it doesn't beat other Python answer, as long as it is different (not the same algorythm/idea), you can post it :). \$\endgroup\$ – Katenkyo Dec 22 '15 at 15:17
  • \$\begingroup\$ @manatwork Thanks! I got another 9 bytes off with that. \$\endgroup\$ – Teemu Piippo Dec 22 '15 at 15:34
2
\$\begingroup\$

APL, 32 31×0.8=24.8 bytes

{¯4↑¨⊃∘(⎕D,⎕A)¨¨⍵⊥⍣¯1¨∘.×⍨1+⍳⍵}

In origin 0. In English:

  • ∘.×⍨1+⍳⍵: multiplication table
  • ⍵⊥⍣¯1¨: express in base ⍵ each element of the multiplication table
  • ⊃∘(⎕D,⎕A)¨¨: convert the table of vector of numbers into a table of vectors of chars
  • ¯4↑¨: right align to length 4 each element of the result

The default APL print routine does the right thing.

      {¯4↑¨(⍵⊥⍣¯1¨∘.×⍨1+⍳⍵)⊃¨¨⊂⊂⎕D,⎕A}13
    1     2     3     4     5     6     7     8     9     A     B     C    10 
    2     4     6     8     A     C    11    13    15    17    19    1B    20 
    3     6     9     C    12    15    18    1B    21    24    27    2A    30 
    4     8     C    13    17    1B    22    26    2A    31    35    39    40 
    5     A    12    17    1C    24    29    31    36    3B    43    48    50 
    6     C    15    1B    24    2A    33    39    42    48    51    57    60 
    7    11    18    22    29    33    3A    44    4B    55    5C    66    70 
    8    13    1B    26    31    39    44    4C    57    62    6A    75    80 
    9    15    21    2A    36    42    4B    57    63    6C    78    84    90 
    A    17    24    31    3B    48    55    62    6C    79    86    93    A0 
    B    19    27    35    43    51    5C    6A    78    86    94    A2    B0 
    C    1B    2A    39    48    57    66    75    84    93    A2    B1    C0 
   10    20    30    40    50    60    70    80    90    A0    B0    C0   100 
\$\endgroup\$
  • \$\begingroup\$ –1: {¯4↑¨⊃∘(⎕D,⎕A)¨¨⍵⊥⍣¯1¨∘.×⍨1+⍳⍵} \$\endgroup\$ – Adám Jun 28 '16 at 15:40
  • \$\begingroup\$ Instead of "chars" you should use "bytes" with a link to meta.codegolf.stackexchange.com/a/9429/43319. \$\endgroup\$ – Adám Jun 28 '16 at 15:42
1
\$\begingroup\$

Ruby, 69 66 characters - 20% = 52.8

->n{(r=1..n).map{|a|puts r.map{|b|"%4s"%(a*b).to_s(n).upcase}*''}}

Sample run:

2.1.5 :001 > ->n{(r=1..n).map{|a|puts r.map{|b|"%4s"%(a*b).to_s(n).upcase}*''}}[4]
   1   2   3  10
   2  10  12  20
   3  12  21  30
  10  20  30 100
\$\endgroup\$
1
\$\begingroup\$

ksh93, 51 * 0.8 == 40.8 bytes

eval echo "'
' {"{1..$1}'..$((++n*$1))..$n%3..$1d}'

This should work up to base 64 (the largest radix supported by ksh). Examples:

 $ n= ksh -s 12 <<\EOF
eval echo "'
' {"{1..$1}'..$((++n*$1))..$n%3..$1d}'
EOF


   1   2   3   4   5   6   7   8   9   a   b  10
   2   4   6   8   a  10  12  14  16  18  1a  20
   3   6   9  10  13  16  19  20  23  26  29  30
   4   8  10  14  18  20  24  28  30  34  38  40
   5   a  13  18  21  26  2b  34  39  42  47  50
   6  10  16  20  26  30  36  40  46  50  56  60
   7  12  19  24  2b  36  41  48  53  5a  65  70
   8  14  20  28  34  40  48  54  60  68  74  80
   9  16  23  30  39  46  53  60  69  76  83  90
   a  18  26  34  42  50  5a  68  76  84  92  a0
   b  1a  29  38  47  56  65  74  83  92  a1  b0
  10  20  30  40  50  60  70  80  90  a0  b0 100

 $ n= ksh -s 22 <<\EOF
eval echo "'
' {"{1..$1}'..$((++n*$1))..$n%3..$1d}'
EOF


   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f   g   h   i   j   k   l  10
   2   4   6   8   a   c   e   g   i   k  10  12  14  16  18  1a  1c  1e  1g  1i  1k  20
   3   6   9   c   f   i   l  12  15  18  1b  1e  1h  1k  21  24  27  2a  2d  2g  2j  30
   4   8   c   g   k  12  16  1a  1e  1i  20  24  28  2c  2g  2k  32  36  3a  3e  3i  40
   5   a   f   k  13  18  1d  1i  21  26  2b  2g  2l  34  39  3e  3j  42  47  4c  4h  50
   6   c   i  12  18  1e  1k  24  2a  2g  30  36  3c  3i  42  48  4e  4k  54  5a  5g  60
   7   e   l  16  1d  1k  25  2c  2j  34  3b  3i  43  4a  4h  52  59  5g  61  68  6f  70
   8   g  12  1a  1i  24  2c  2k  36  3e  40  48  4g  52  5a  5i  64  6c  6k  76  7e  80
   9   i  15  1e  21  2a  2j  36  3f  42  4b  4k  57  5g  63  6c  6l  78  7h  84  8d  90
   a   k  18  1i  26  2g  34  3e  42  4c  50  5a  5k  68  6i  76  7g  84  8e  92  9c  a0
   b  10  1b  20  2b  30  3b  40  4b  50  5b  60  6b  70  7b  80  8b  90  9b  a0  ab  b0
   c  12  1e  24  2g  36  3i  48  4k  5a  60  6c  72  7e  84  8g  96  9i  a8  ak  ba  c0
   d  14  1h  28  2l  3c  43  4g  57  5k  6b  72  7f  86  8j  9a  a1  ae  b5  bi  c9  d0
   e  16  1k  2c  34  3i  4a  52  5g  68  70  7e  86  8k  9c  a4  ai  ba  c2  cg  d8  e0
   f  18  21  2g  39  42  4h  5a  63  6i  7b  84  8j  9c  a5  ak  bd  c6  cl  de  e7  f0
   g  1a  24  2k  3e  48  52  5i  6c  76  80  8g  9a  a4  ak  be  c8  d2  di  ec  f6  g0
   h  1c  27  32  3j  4e  59  64  6l  7g  8b  96  a1  ai  bd  c8  d3  dk  ef  fa  g5  h0
   i  1e  2a  36  42  4k  5g  6c  78  84  90  9i  ae  ba  c6  d2  dk  eg  fc  g8  h4  i0
   j  1g  2d  3a  47  54  61  6k  7h  8e  9b  a8  b5  c2  cl  di  ef  fc  g9  h6  i3  j0
   k  1i  2g  3e  4c  5a  68  76  84  92  a0  ak  bi  cg  de  ec  fa  g8  h6  i4  j2  k0
   l  1k  2j  3i  4h  5g  6f  7e  8d  9c  ab  ba  c9  d8  e7  f6  g5  h4  i3  j2  k1  l0
  10  20  30  40  50  60  70  80  90  a0  b0  c0  d0  e0  f0  g0  h0  i0  j0  k0  l0 100
\$\endgroup\$
0
\$\begingroup\$

Pyke, 14 bytes * 0.8 = 11.2 bytes, noncompetitive

QhD]UA*MbQMl2P

Try it here!

Explanation:

            - autoassign Q = eval_or_not_input()
QhD]        - [Q+1, Q+1]
    U       - nd_range(^)
     A*     - apply(*, ^)
       MbQ  - map(base(Q), ^)
          Ml2 - map(lower, ^)
          P - print_grid(^)

Or 12 bytes without the bonus

13D]UA*Mb12P
\$\endgroup\$
  • \$\begingroup\$ The challenge specifies uppercase letters \$\endgroup\$ – Luis Mendo Mar 31 '16 at 20:59

Your Answer

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

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