Print this tic-tac-toe board!

9

3

Here is a tic-tac-toe board:

   a     b     c
      |     |     
1  -  |  -  |  -  
 _____|_____|_____
      |     |     
2  -  |  -  |  -  
 _____|_____|_____
      |     |     
3  -  |  -  |  -  
      |     |     

Given a set of moves, print the board with the tokens on.

Input will be taken in as moves separated by spaces, with each move being:

  • First, the token that's going
  • Next, the letter of the column it is moving on
  • Last, the number of the row it is moving on

Note that normal tic-tac-toe rules don't matter.

Also, there is no need to print the letters and numbers.

For example, the input Ob2 Xc2 Ob3 Xa1 would result in

     |     |     
  X  |  -  |  -  
_____|_____|_____
     |     |     
  -  |  O  |  X  
_____|_____|_____
     |     |     
  -  |  O  |  -  
     |     |     

Remember, this is , so the code with the smallest number of bytes wins.

Leaderboards

Here is a Stack Snippet to generate both a regular leaderboard and an overview of winners by language.

To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:

# Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

# Ruby, <s>104</s> <s>101</s> 96 bytes

If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:

# Perl, 43 + 2 (-p flag) = 45 bytes

You can also make the language name a link which will then show up in the leaderboard snippet:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes

var QUESTION_ID=95629,OVERRIDE_USER=12537;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

Oliver Ni

Posted 2016-10-07T21:59:03.307

Reputation: 9 650

A thing to avoid with writing challenges is Cumbersome I/O formats. Please make your input format flexible enough. Next time try the Sandbox.

– Erik the Outgolfer – 2016-10-08T10:08:47.317

1@EriktheGolfer cumbersome? This input format is plain and obvious – edc65 – 2016-10-08T12:45:53.617

@edc65 I meant that, I want to get input in any format, not just this one, but I guess it's late by now. I think you mean it's visually clear, but I couldn't handle it at all. Why spaces and not some other separator for example? – Erik the Outgolfer – 2016-10-08T13:58:55.890

1@EriktheGolfer don't take me wrong, but if your super extra esoteric language cannot handle blank spaces, too bad ... you'll have to use something else just this time. – edc65 – 2016-10-08T14:02:30.763

1@edc65 For example, in Sesos it would be pretty difficult to even load the input data. I would prefer a list of integers (three ints for one move), like 1 2 3 for Xb3 (doesn't have to be exactly that). – Erik the Outgolfer – 2016-10-08T14:06:28.297

I think it should remain there for at least 2 days, or until you think you've got enough feedback, and are ready to post it. Impatience might result in downvotes (I haven't downvoted, by the way). – Erik the Outgolfer – 2016-10-08T14:40:05.917

Does the output need to be a string, or can it be formatted using a built-in, like this or this? (the I/O formatting makes my code 2x longer...)

– JungHwan Min – 2016-10-08T15:14:28.427

@JHM It just needs to be in the format it is in the question. – Oliver Ni – 2016-10-08T20:39:36.780

Answers

7

JavaScript (ES6), 136 133 129 bytes

let f =

i=>eval("for(y=9,s='';y--;s+=`\n`)for(x=18;--x;)s+=x%6-3|y%3-1?' __|'[x%6?y/3:3]||' ':i[i.search('cba'[x/6|0]+(10-y)/3)-1]||'-'")

console.log(f("Ob2 Xc2 Ob3 Xa1"))

Arnauld

Posted 2016-10-07T21:59:03.307

Reputation: 111 334

5

Python (2.7), 188 180 bytes

def f(s):a,b=3*[' '*5],3*['_'*5];c,d,e=[['  '+dict((m[1:],m[0])for m in s.split(' ')).get(x+y,'-')+'  'for x in'abc']for y in'123'];print'\n'.join(map('|'.join,[a,c,b,a,d,b,a,e,a]))

Joshua David

Posted 2016-10-07T21:59:03.307

Reputation: 211

In the third line you can remove the spaces before the 's – Daniel – 2016-10-08T02:09:02.890

Welcome to python golfing! Take a look at the Python golf tips. You can separate statements with ; allowing you to put all your code on one line to save on indentation.

– xnor – 2016-10-08T03:07:53.923

for y in '123' -> for y in'123'. Also, what xnor said: you can make your function a one-liner, using ; to separate statements. Using all of these golfing tips, you can golf 6 bytes. – Erik the Outgolfer – 2016-10-08T09:55:29.497

4

Python 2, 112 bytes

s=input()+'- '
r=3;exec"print'|'.join([' '*5,'  %s  '%s[s.find(c+`r/3`)-1],'_'*5][r%11%3]for c in'abc');r+=1;"*9

Nine rows are printed corresponding to row indices r. The row index is counted up from 3 to 11 in an exec loop. Each row consists of vertical lines | joining three 5-character segments that cycle between:

  • Five spaces
  • Two spaces, a player symbol, then two spaces
  • Five underscores

The type is made to cycle with r%3, except the last row has spaces rather than underscores, achieved with r%11%3.

To find the player symbol for the current cell, we look at the row number r/3 and the column letter c from "abc". We concatenate them to make a two-character string like b3, find the index of it in the input string, and then take the symbol (X or O) one index earlier. If neither player played there, the find will default to -1, which decrements to -2. We hack s[-2] to be - by appending two characters when we take input.

xnor

Posted 2016-10-07T21:59:03.307

Reputation: 115 687

1

Batch, 341 339 305 287 bytes

@for %%a in (a1 a2 a3 b1 b2 b3 c1 c2 c3)do @set %%a=-
@for %%a in (%*)do @set s=%%a&call call set %%s:~1%%=%%s:~0,1%%
@set s="     |     |     "
@for %%l in (%s% "  %a1%  |  %b1%  |  %c1%" %s: =_% %s% "  %a2%  |  %b2%  |  %c2%" %s: =_% %s% "  %a3%  |  %b3%  |  %c3%" %s%)do @echo %%~l

Assumes consistent output. Edit: Saved 2 bytes by removing unnecessary spaces. Saved 34 bytes by writing the output using a for loop. Saved 18 bytes by eliminating the subroutine.

Neil

Posted 2016-10-07T21:59:03.307

Reputation: 95 035

1

Java, 138 bytes

Edit:

  • -2 bytes off. Thanks to @Kevin Kruijssen

Snipet:

m->{char[][]o=new char[3][3];for(char[]a:m)o[a[1]-'a'][a[2]-'0']=a[0];for(char[]a:o)System.out.println(a[0]+'|'+a[1]+'|'+a[2]+"\n-----");}

Code:

public static void tictactoe(char[][]moves){
  char[][]o=new char[3][3];
  for(char[]a:moves){
    o[a[1]-79][a[2]-48]=a[0];
  }
  for(char[]a:o){
    System.out.println(a[0]+'|'+a[1]+'|'+a[2]+"\n-----");
  }
}

Roman Gräf

Posted 2016-10-07T21:59:03.307

Reputation: 2 915

o[a[1]-'a'][a[2]-'0']=a[0] can be golfed by two bytes to o[a[1]-97][a[2]-48]=a[0] – Kevin Cruijssen – 2016-10-10T11:53:06.120

but if's the wrong output, isn't it? – norganos – 2016-10-11T05:33:25.017

Which mistake do you mean? – Roman Gräf – 2016-10-11T05:34:26.570

The output format is not the same as asked by the OP. – seshoumara – 2017-02-21T19:32:38.687

1

PHP, 187 Bytes

<?for(;$i++<162;)$s.=$i%18?($i%6?($i<144&&$i%54>36?"_":($i<144&&$i%54>18&&$i%6==3?"-":" ")):"|"):"\n";foreach(explode(" ",$_GET[a])as$t)$s[20+6*(1+($t[1]<=>b))+54*($t[2]-1)]=$t[0];echo$s;

Takes the input as string. If I could use an array it can be reduce to $_GET[a] instead of explode(" ",$_GET[a])

207 Bytes

<?foreach(explode(" ",$_GET[a])as$t)$a[(1+($t[1]<=>b))+3*($t[2]-1)]=$t[0];for(;$i++<162;)$s.=$i%18?($i%6?($i<144&&$i%54>36?"_":" "):"|"):"\n";for(;$x<9;)$s[18+54*(($x/3)^0)+2+6*($x%3)]=$a[+$x++]??"-";echo$s;

The simplest idea to create this 194 Bytes

<?for(;++$i<10;)$s.=($i==9||$i%3?($i%3==2?"  -  |  -  |  -  ":"     |     |     "):"_____|_____|_____")."\n";foreach(explode(" ",$_GET[a])as$t)$s[20+6*(1+($t[1]<=>b))+54*($t[2]-1)]=$t[0];echo$s;

Jörg Hülsermann

Posted 2016-10-07T21:59:03.307

Reputation: 13 026

1

Mathematica, 205 bytes

StringReplacePart[a="     |     |     
";b="  -  |  -  |  -  
";c="_____|_____|_____
";{a,b,c,a,b,c,a,b,a}<>"",##]&@@Transpose[{#,{#,#}&[54LetterNumber@#2+6FromDigits@#3-39]}&@@@Characters/@StringSplit@#]&

This would be way shorter if I could use the built-in... (92 bytes)

Grid@SparseArray[{LetterNumber@#2,FromDigits@#3}->#&@@@Characters/@StringSplit@#,{3,3},"-"]&

JungHwan Min

Posted 2016-10-07T21:59:03.307

Reputation: 13 290

0

Autovim, 110 bytes (not competing)

Test driving Autovim... This is pretty much a Vimscript answer. Not competing because Autovim is still being developed.

ñ5i ␛a|␛ÿp3hr-phv0r_⌥v$kkyPPy2jPP$⌥vG$xGđkÿjp
…nsplit(@m)
ñğ0(@n[2]*3-2)j((char2nr(@n[1])-96)*6-4)lr(@n[0])
e…

To run it:

./bin/autovim run tictactoe.autovim -ni -@m "Ob2 Xc2 Ob3 Xa1"

Ungolfed:

execute "normal 5i \<esc>a|\<esc>yyp3hr-phv0r_\<c-v>$kkyPPy2jPP$\<c-v>G$xGddkyyjp"
for @n in split(@m)
execute "normal gg0".(@n[2]*3-2)."j".((char2nr(@n[1])-96)*6-4)."lr".(@n[0]).""
endfor

Explanation to follow if there is interest :)

Christian Rondeau

Posted 2016-10-07T21:59:03.307

Reputation: 301

0

Groovy, 174 Bytes

{s->def r=0,o,t=[:];s.split(' ').each{t[it[1..2]]=it[0]};9.times{y->o='';17.times{x->o+=x%6==5?'|':y in [2,5]?'_':x%6==2&&y%3==1?t['abc'[r++%3]+(y+2)/3]?:'-':' '};println o}}

ungolfed:

{s->
    def r=0, o, t=[:];
    s.split(' ').each{
        t[it[1..2]]=it[0]
    };
    9.times{y->
        o='';
        17.times{x->
            o+= x%6==5 ? '|' : y in [2,5]? '_' : x%6==2 && y%3==1 ? t['abc'[r++%3]+(y+2)/3]?:'-' : ' '
        };
        println o
    }
}

norganos

Posted 2016-10-07T21:59:03.307

Reputation: 51

0

CJam, 62 bytes

" -_ -_ - "_'-Ser_+_@\]3*sqS/{)~\)'a-F*@+3*G+\t}/9/5/'|9*a*zN*

Try it online

Explanation:

" -_ -_ - "_'-Ser_+_@\]3*s e# Build a 135 character string representing the 
                           e# columns of the board (top to bottom, left to right)
qS/{)~\)'a-F*@+3*G+\t}/    e# Process the input, put the tokens (O,X) in the string
                           e# The tokens have to placed at indexes 
                           e# [19 22 25 64 67 70 109 112 115]
                           e# This is done with the formula 3*(15x+y)+16,
                           e# where x is the code point of the column letter 
                           e# (minus 'a') and y is the row number.
9/5/'|9*a*zN*              e# Split into its parts, add the column separators, zip 
                           e# and join with newlines.

Neorej

Posted 2016-10-07T21:59:03.307

Reputation: 179