A multiplication table for the Cheela

26

2

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).

Luis Mendo

Posted 2015-12-20T17:09:45.507

Reputation: 87 464

Nice one Luis! =) I wish I had the time to come up with a MATLAB solution, but I'm busy measuring Christmas gift dimensions... – Stewie Griffin – 2015-12-20T18:23:59.163

6Good luck with those spherical hats! :-P – Luis Mendo – 2015-12-20T18:26:51.027

5Because they have twelve eyes, they naturally use a base-12 numbering system. Well, naturally. That's why we use binary, after all... ;-) – Tim Pederick – 2015-12-21T13:34:27.173

2@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! – Luis Mendo – 2015-12-21T13:44:44.040

1@LuisMendo very nice novel, the one you quote. Starquake isn't bad either. – lstefano – 2016-06-28T16:10:09.767

@Istefano Finally someone who has read it! :-) I loved it. I also read Starquake, but I enjoyed it slightly less. Maybe because I had already read the first one, so the element of surprise had been lost a little – Luis Mendo – 2016-06-28T16:21:01.713

Answers

14

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

Jakube

Posted 2015-12-20T17:09:45.507

Reputation: 21 462

11

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

Martin Ender

Posted 2015-12-20T17:09:45.507

Reputation: 184 808

8

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.

Luis Mendo

Posted 2015-12-20T17:09:45.507

Reputation: 87 464

"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? – Alex A. – 2015-12-20T19:18:48.393

1@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? – Luis Mendo – 2015-12-20T19:21:18.187

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. – Alex A. – 2015-12-20T19:24:36.530

@AlexA. Good idea! Done

– Luis Mendo – 2015-12-20T19:35:13.800

@AlexA. If you feel like doing it, maybe add your suggestion as an answer there? – Luis Mendo – 2015-12-20T19:40:09.607

5

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.

Digital Trauma

Posted 2015-12-20T17:09:45.507

Reputation: 64 644

4

Pyth, 36 bytes

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

Try it here.

Blue

Posted 2015-12-20T17:09:45.507

Reputation: 26 661

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 – Jakube – 2015-12-20T18:12:31.393

4

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.

geokavel

Posted 2015-12-20T17:09:45.507

Reputation: 6 352

4

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! :)

basile-henry

Posted 2015-12-20T17:09:45.507

Reputation: 381

Upvoted, because the more I golf my answer, the more it starts to look like yours!

– Tim Pederick – 2015-12-21T06:07:32.523

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.

– Tim Pederick – 2015-12-21T12:06:10.137

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 :) – basile-henry – 2015-12-21T12:33:55.487

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. – Tim Pederick – 2015-12-21T12:39:32.010

Yes that's the reason I used this part of your code exploiting python 2 to save one more byte :) – basile-henry – 2015-12-21T12:40:59.643

By the way this ternary form: does "and" have precedence over "or" or is it just a left to right kind of thing? Also I'm not too sure why it returns the value of f or '' instead of just true – basile-henry – 2015-12-21T12:43:15.847

3

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

Brad Gilbert b2gills

Posted 2015-12-20T17:09:45.507

Reputation: 12 713

Not an expert, but is the space between 'for' and '(' required? Gotta clip the spaces where possible. – J_F_B_M – 2015-12-20T20:37:25.967

@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. – Brad Gilbert b2gills – 2015-12-20T23:03:54.550

Learned something. Thank you. – J_F_B_M – 2015-12-20T23:19:48.423

3

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!

Tim Pederick

Posted 2015-12-20T17:09:45.507

Reputation: 1 411

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! – basile-henry – 2015-12-21T10:45:57.227

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... – basile-henry – 2015-12-21T11:02:41.263

@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. – Tim Pederick – 2015-12-21T11:40:44.213

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 ^^ – basile-henry – 2015-12-21T11:53:52.937

@Boomerang: Hey, yours was first, and I think Python 2 offers enough shortcuts that you could still overtake me. But thanks for the help! – Tim Pederick – 2015-12-21T11:59:30.230

If you do this trick you can gain one more byte by having i=... and R=... on the same line (basically replacing "\n " by ";") – basile-henry – 2015-12-21T11:59:36.787

3

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)
}

edc65

Posted 2015-12-20T17:09:45.507

Reputation: 31 086

3

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

Aᴄʜᴇʀᴏɴғᴀɪʟ

Posted 2015-12-20T17:09:45.507

Reputation: 276

1Simply 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() – edc65 – 2015-12-21T09:47:48.253

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)...? – Aᴄʜᴇʀᴏɴғᴀɪʟ – 2015-12-22T05:57:39.740

Ugh sorry you're right about a. +1 as is – edc65 – 2015-12-22T07:38:17.933

2

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 :)

brainkz

Posted 2015-12-20T17:09:45.507

Reputation: 349

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) – Luis Mendo – 2015-12-21T18:11:11.820

1Oh and welcome to the site! :-) – Luis Mendo – 2015-12-21T18:12:29.473

@LuisMendo thanks! I'll edit my answer with @(N) notation – brainkz – 2015-12-21T18:24:39.317

2

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)))

Teemu Piippo

Posted 2015-12-20T17:09:45.507

Reputation: 121

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.

– manatwork – 2015-12-22T15:12:17.897

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 :). – Katenkyo – 2015-12-22T15:17:49.147

@manatwork Thanks! I got another 9 bytes off with that. – Teemu Piippo – 2015-12-22T15:34:41.377

2

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 

lstefano

Posted 2015-12-20T17:09:45.507

Reputation: 850

–1: {¯4↑¨⊃∘(⎕D,⎕A)¨¨⍵⊥⍣¯1¨∘.×⍨1+⍳⍵} – Adám – 2016-06-28T15:40:08.680

Instead of "chars" you should use "bytes" with a link to http://meta.codegolf.stackexchange.com/a/9429/43319.

– Adám – 2016-06-28T15:42:05.163

1

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

manatwork

Posted 2015-12-20T17:09:45.507

Reputation: 17 865

1

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

ormaaj

Posted 2015-12-20T17:09:45.507

Reputation: 153

0

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

Blue

Posted 2015-12-20T17:09:45.507

Reputation: 26 661

The challenge specifies uppercase letters – Luis Mendo – 2016-03-31T20:59:29.623