This challenge will behave more or less like a traditional . The only difference is that instead of scoring answers by their number of characters or bytes, users will assign weights to different characters in the comments and the program with the lowest cumulative weight will win.


Your task is to write a program that takes a string and prints a diamond shape where the first character starts in the center and subsequent characters occupy the empty spaces orthogonal to the set of characters that were placed last. Spaces ( ) will be used for padding.

For example inputting CAT would produce


and () would produce


and  desserts would produce

stressed desserts

and 9 would produce 9.


  • The code may only contain printable ASCII and newlines. (See why below.)

  • Input/output should be via stdin/stdout, or, if they aren't possible, use similar alternatives.

  • You may assume the input string only contains printable ASCII (including space).

  • Columns of leading spaces not containing any portion of the diamond pattern are not allowed in the output. Any amount and combination of trailing spaces spaces is allowed.

  • There may optionally be a trailing newline in the output.

  • You may edit your answer as much as you want.


All code must be written using only newlines and the 95 printable ASCII characters:


(Sadly tabs are not allowed because Stack Exchange renders them as spaces in code blocks.)

Each of these 96 characters has a weight value associated with it. By default, all the weights are 97.

The score of a program is the sum of the weight values for each of its characters. For example, if the program were print(4) and the weight for 4 was 70, but unchanged for everything else, the score would be 749 = 97+97+97+97+97+97+70+97.

Once the activity in this question settles down to almost nothing, the lowest scoring submission wins. In the presumably unlikely case of tie the wins goes to the highest voted answer.

Changing Weights

Every user, whether they've answered or not, can change the weight of one of the 96 characters to a unique value from 1 to 96. To do this, add a comment to this question of the form #### W -> C ####, where W is an integer from 1 to 96 and C is the character (as itself, no quotes, no backticks). Use \n in place of C for newlines and \s for space since Stack Exchange compresses 3 spaces in a row. The print(4) example above would have had the comment #### 70 -> 4 ####.

Each user may only make ONE comment like this, and it will only be valid if both the character and the weight value have not been used in a previously made comment. Thus eventually, there may be 96 #### W -> C #### comments, all from different users, all with different weights assigned to different characters.

Users may delete their own comment if they want to, resetting their characters' weight back to 97 until they or someone else comments again. They may also edit them. Comments not following the rules about distinct users/weights/characters should be deleted or flagged as "not constructive". General comments about rules and other things are fine but should be kept at a minimum.

This stack snippet is the official leaderboard for this question. It automatically computes the scores for all submissions by gathering the weights from comments each time it is run. It does not handle ties. You can also use it to check the score a program would have.

You'll probably need to right-click -> Open link in new tab for the links.

function compute(){var e=computeScore($("#code").val());$("#score").val(e==-1?"Invalid characters":e)}function computeScore(e){var t=0;for(var n=0;n<e.length;n++){if(weights.hasOwnProperty(e[n])){t+=weights[e[n]]}else{return-1}}return t}function htmlDecode(e){var t=document.createElement("div");t.innerHTML=e;return t.childNodes.length===0?"":t.childNodes[0].nodeValue}function addLeaderboard(){validAnswers.sort(function(e,t){return e.score>t.score});var e=1;var t="";for(var n=0;n<validAnswers.length;n++){var r=validAnswers[n];t+="<tr><td>"+e+"</td><td><a href='"+r.link+"'>"+r.owner.display_name+"</a></td><td>"+r.score+"</td><td>"+r.length+"</td></tr>";if(n+1<validAnswers.length&&validAnswers[n+1].score>r.score){e++}}$("#leaderboard").append(t)}function addAnalytics(){var e="";for(var t in weights){if(weights.hasOwnProperty(t)&&weights[t]!=defaultWeight){e+=(t=="\n"?"\\n":t)+"="+weights[t]+" "}}$("#weights").val(e);var n="";for(var t in usedChars){if(usedChars.hasOwnProperty(t)&&usedChars[t]==false){n+=t=="\n"?"\\n":t}}$("#unusedc").val(n);var r="";for(var t in usedWeights){if(usedWeights.hasOwnProperty(t)&&usedWeights[t]==false){r+=t+" "}}$("#unusedw").val(r);var i="";if(invalidComments.length>0){for(var s=0;s<invalidComments.length;s++){var o=invalidComments[s];i+="<a href='#"+o.link+"'>"+o.owner.display_name+"</a> "}}else{i="none"}$("#comments").html(i);var u="";if(invalidAnswers.length>0){for(var s=0;s<invalidAnswers.length;s++){var a=invalidAnswers[s];u+="<a href='#"+a.link+"'>"+a.owner.display_name+"</a> "}}else{u="none"}$("#answers").html(u)}function checkAnswers(e){for(var t=0;t<e.items.length;t++){var n=e.items[t];var r=answerPattern.exec(n.body);if(r){var i=htmlDecode(r[1]);var s=computeScore(i);if(s==-1){invalidAnswers.push(n)}else{n.length=i.length;n.score=s;validAnswers.push(n)}}else{invalidAnswers.push(n)}}addLeaderboard();addAnalytics()}function checkComments(e){for(var t=0;t<e.items.length;t++){var n=e.items[t];var r=commentPattern.exec(htmlDecode(n.body));if(r){var i=n.owner.user_id;var s=parseInt(r[1]);var o=r[2]=="\\n"?"\n":r[2]=="\\s"?" ":r[2];if(userIDs.hasOwnProperty(i)||!usedWeights.hasOwnProperty(s)||usedWeights[s]||!usedChars.hasOwnProperty(o)||usedChars[o]){invalidComments.push(n)}else{userIDs[i]=true;usedWeights[s]=true;usedChars[o]=true;weights[o]=s}}}$.get(answersURL,checkAnswers)}function refresh(){$.get(commentsURL,checkComments)}questionID=45040;commentsURL="https://api.stackexchange.com/2.2/questions/"+questionID+"/comments?order=asc&sort=creation&site=codegolf&filter=!t)IWLXOkOvAuPe8m2xJrXOknWcw(ZqZ";answersURL="https://api.stackexchange.com/2.2/questions/"+questionID+"/answers?order=desc&sort=activity&site=codegolf&filter=!.FjsvG2LuND(frE*)WTvqQev1.lyu";commentPattern=/^#### (\d+) -> (\\(?:n|s)|[ -~]) ####$/;answerPattern=/<pre><code>((?:\n|.)*?)\n<\/code><\/pre>/;chars="\n !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";validAnswers=[];invalidAnswers=[];invalidComments=[];userIDs={};usedWeights={};usedChars={};weights={};defaultWeight=chars.length+1;for(var i=0;i<chars.length;i++){usedChars[chars[i]]=false;usedWeights[i+1]=false;weights[chars[i]]=defaultWeight}refresh()
*{font-family:Helvetica,Arial,sans-serif}table{border:3px solid green;border-collapse:collapse}button{font-size:100%}th{background-color:green;color:#fff;padding:6pt}td{border:1px solid green;padding:6pt}.large{font-size:140%}.title{font-weight:700;margin:6pt 0}textarea{font-family:"Courier New";white-space:nowrap;overflow:auto}input[readonly]{background-color:#dcdcdc}.analytics{font-size:90%;padding:4pt 0 0}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><div class='large title'>Leaderboard</div><table id='leaderboard'> <tr> <th>Place</th> <th>Submitter</th> <th>Score</th> <th>Program Length</th> </tr></table><br><div class='title'>Compute Score</div><textarea id='code' rows='5' cols='40' placeholder='paste code here...'></textarea><br><button type='button' onclick='compute()'>Compute</button> Score: <input type='text' id='score' readonly><br><br><div class='title'>Analytics</div><div class='analytics'>Assigned weights: <input type='text' id='weights' readonly></div><div class='analytics'>Unused characters: <input type='text' id='unusedc' readonly> (all weight 97)</div><div class='analytics'>Unused weights: <input type='text' id='unusedw' readonly></div><div class='analytics'>Invalid comments (duplicate user/char/weight):&nbsp;<span id='comments'></span></div><div class='analytics'>Invalid answers (illegal characters or no code block):&nbsp;<span id='answers'><span></div><br><button type='button' onclick='refresh'>Refresh</button>

For this leaderboard to work, the comments must be in the exact format described above and your program's code must be in the first multi-line code block in your answer (the <pre><code>...</code></pre> ones). Don't use syntax highlighting or your code won't be read correctly. The snippet can take a minute or two before it updates.

I have not tested the snippet thoroughly but I'll be keeping an eye on it as this contest gets underway. If you notice any bugs please tell me. Here is an non-minified version:

questionID = 45040

commentsURL = 'https://api.stackexchange.com/2.2/questions/' + questionID + '/comments?order=asc&sort=creation&site=codegolf&filter=!t)IWLXOkOvAuPe8m2xJrXOknWcw(ZqZ'

answersURL = 'https://api.stackexchange.com/2.2/questions/' + questionID + '/answers?order=desc&sort=activity&site=codegolf&filter=!.FjsvG2LuND(frE*)WTvqQev1.lyu'

commentPattern = /^#### (\d+) -> (\\(?:n|s)|[ -~]) ####$/
answerPattern = /<pre><code>((?:\n|.)*?)\n<\/code><\/pre>/

chars = '\n !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'

validAnswers = []
invalidAnswers = []
invalidComments = []

userIDs = {}
usedWeights = {}
usedChars = {}
weights = {}
defaultWeight = chars.length + 1

for (var i = 0; i < chars.length; i++) {
    usedChars[chars[i]] = false
    usedWeights[i + 1] = false
    weights[chars[i]] = defaultWeight

function compute() {
    var score = computeScore($('#code').val())    
    $('#score').val(score == -1 ? 'Invalid characters' : score)

function computeScore(code) {
    var score = 0
    for(var i = 0; i < code.length; i++) {
        if (weights.hasOwnProperty(code[i])) {
            score += weights[code[i]]   
        } else {
            return -1
    return score

function htmlDecode(input)  {
  var e = document.createElement('div')
  e.innerHTML = input;
  return e.childNodes.length === 0 ? '' : e.childNodes[0].nodeValue

function addLeaderboard() {
    validAnswers.sort(function(a,b) { return a.score > b.score} )
    var place = 1
    var rows = ''
    for(var i = 0; i < validAnswers.length; i++) {
       var a = validAnswers[i]
       rows +=
           '<tr><td>' + place +
           "</td><td><a href='" + a.link + "'>" + a.owner.display_name + "</a></td><td>" +
           a.score + '</td><td>' + a.length + '</td></tr>'
       if (i + 1 < validAnswers.length && validAnswers[i + 1].score > a.score) {

function addAnalytics() {
    //assigned weights
    var assigned = ''
    for (var key in weights) {
        if (weights.hasOwnProperty(key) && weights[key] != defaultWeight) {
            assigned += (key == '\n' ? '\\n' : key) + '=' + weights[key] + ' '
    //unused chars
    var unusedc = ''
    for (var key in usedChars) {
        if (usedChars.hasOwnProperty(key) && usedChars[key] == false) {
            unusedc += key == '\n' ? '\\n' : key
    //unused weights
    var unusedw = ''
    for (var key in usedWeights) {
        if (usedWeights.hasOwnProperty(key) && usedWeights[key] == false) {
            unusedw += key + ' '
    //invalid comments
    var invalidc = ''
    if (invalidComments.length > 0) {
        for (var i = 0; i < invalidComments.length; i++) {
            var c = invalidComments[i]
            invalidc += "<a href='#" + c.link + "'>" + c.owner.display_name + '</a> '
    } else {
        invalidc = 'none'
    //invalid answers
    var invalida = ''
    if (invalidAnswers.length > 0) {
        for (var i = 0; i < invalidAnswers.length; i++) {
            var a = invalidAnswers[i]
            invalida += "<a href='#" + a.link + "'>" + a.owner.display_name + '</a> '
    } else {
        invalida = 'none'   

function checkAnswers(answers) {
    for (var i = 0; i < answers.items.length; i++) {
        var answer = answers.items[i]
        var match = answerPattern.exec(answer.body)
        if (match) {
            var code = htmlDecode(match[1])
            var score = computeScore(code)
            if (score == -1) {
            } else {
                answer.length = code.length
                answer.score = score
        } else {

function checkComments(comments) {
    for (var i = 0; i < comments.items.length; i++) {
        var comment = comments.items[i]
        var match = commentPattern.exec(htmlDecode(comment.body))
        if (match) {
            var userID = comment.owner.user_id            
            var weight = parseInt(match[1])
            var char = match[2] == '\\n' ? '\n' : (match[2] == '\\s' ? ' ' : match[2])

            //check validity
            if (userIDs.hasOwnProperty(userID) ||
                !usedWeights.hasOwnProperty(weight) || usedWeights[weight] ||
                !usedChars.hasOwnProperty(char) || usedChars[char])
            } else {
                userIDs[userID] = true
                usedWeights[weight] = true
                usedChars[char] = true
                weights[char] = weight
    $.get(answersURL, checkAnswers)

function refresh() {
    $.get(commentsURL, checkComments)

* {
    font-family: Helvetica, Arial, sans-serif;

table {
    border: 3px solid green;
    border-collapse: collapse;

button {
    font-size: 100%;

th {
    background-color: green;
    color: white;
    padding: 6pt;
td {
    border: 1px solid green;
    padding: 6pt;

    font-size: 140%;

    font-weight: bold;
    margin: 6pt 0 6pt 0;

textarea {
    font-family: "Courier New";
    white-space: nowrap; overflow: auto;

    background-color: gainsboro;

.analytics {
    font-size: 90%;
    padding: 4pt 0 0 0;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='large title'>Leaderboard</div>
<table id='leaderboard'>
    <th>Program Length</th>
<div class='title'>Compute Score</div>
<textarea id='code' rows='5' cols ='40' placeholder='paste code here...'></textarea><br>
<button type='button' onclick='compute()'>Compute</button> Score: <input type='text' id='score' readonly>
<div class='title'>Analytics</div>
<div class='analytics'>Assigned weights: <input type='text' id='weights' readonly></div>
<div class='analytics'>Unused characters: <input type='text' id='unusedc' readonly> (all weight 97)</div>
<div class='analytics'>Unused weights: <input type='text' id='unusedw' readonly></div>
<div class='analytics'>Invalid comments (duplicate user/char/weight):&nbsp;<span id='comments'></span></div>
<div class='analytics'>Invalid answers (illegal characters or no code block):&nbsp;<span id='answers'><span></div>
<button type='button' onclick='refresh'>Refresh</button>

Keep in mind that this scoring system is completely new and experimental. Hopefully Stack Exchange won't mind that it involves tons of comments. :P

Related challenge: Print this diamond

  • \$\begingroup\$ #### 1 -> * #### \$\endgroup\$ – Martin Ender Jan 27 '15 at 12:11
  • \$\begingroup\$ Comments can be edited for 5 minutes, so allowing them to be edited could cause complete havok with the non-repetition rules. \$\endgroup\$ – Peter Taylor Jan 27 '15 at 12:15
  • \$\begingroup\$ @PeterTaylor But how can I possibly stop comment edits? Besides totally ignoring ones that are edited. 5 minutes goes pretty fast. \$\endgroup\$ – Calvin's Hobbies Jan 27 '15 at 12:17
  • 1
    \$\begingroup\$ I don't like this scoring system at all (see chat), but if you're going to use it then ignoring comments which are edited is definitely the right thing to do. \$\endgroup\$ – Peter Taylor Jan 27 '15 at 12:23
  • \$\begingroup\$ #### 2 -> : #### \$\endgroup\$ – Logic Knight Jan 27 '15 at 12:57

CJam, 144 150 bytes


Tried some encoding...

Updated because the weight of b has changed.

Another encoding which is only better in theory (140 bytes):

":***(*3:**3*I**:3*****:*3*******: ::::*:***II@3*******: :**I:**:***:*3***3*I3I:3***33:::*I**3I***3***:3:*I*3I"{"*:I3( **@"#1a*~0}%2b126b:c~

Python 2, 120 bytes

r=[b[::-1]+b[1:]for b in [T[-b:]+' '*(L-b)for b in range(1,L+1)]]
for b in r[:-1]+r[::-1]:print b

Edit: Lowered cost with some cheaper characters.


Pyth, 21 bytes

L+_tbbjbymy+>zd*\ dlz

Try it online: Pyth Compiler/Executor


CJam, 31 bytes


Just an adaptation of my answer to Print this diamond for now. I might tweak it when the weights have changed.

Test it here.


J, 45 chars

(({~((]*]<#@[)>:@(+/~)@:|@i:@(2-#)))@(' '&,))

Longish solution, will golf it with some cheap chars...

Try it online. (Append input string with single quotes.)


PHP (131 chars)

function f($s){for($i=-($l=strlen($s));$i<$l;$I=abs(++$i)){$t=substr($s,$I);echo str_repeat(' ',$I).strrev($t).substr($t,1)."\n";}}


Will optimise once the weightings are clearer.

  • \$\begingroup\$ Your code may be rewritten into this: function f($s){for($i=-($l=strlen($s));$i<$l;)echo str_repeat(' ',$I=abs(++$i)),strrev($t=substr($s,$I)),substr($t,1),"\n";} which might not work. But it is 6 bytes shorter! Probably you might take something from here. \$\endgroup\$ – Ismael Miguel Jan 28 '15 at 17:16

Java, 318 bytes

class N{public static void main(String[]a){char[]s=new java.util.Scanner(System.in).nextLine().toCharArray();int l=s.length,m=l-1,$=0,b;String t="";for(;$<l;$++,t+='\n')for(b=0;b<l+$;b++)t+=b+$<m?' ':s[b>m?m-b+$:b+$-m];for($=l-2;$>-1;$--,t+='\n')for(b=0;b<l+$;b++)t+=b+$<m?' ':s[b>m?m-b+$:b+$-m];System.out.print(t);}}

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.