19
\$\begingroup\$

Let \$R, C\$ be positive integers and let \0ドル < s \leq 1\$. Consider the \$R \times C\$ matrix \$\mathbf M\$ defined as \begin{equation} M(i,j) = \frac{\mathrm{mod},円(j, i^s)}{R^s}, \quad i = 1, \ldots, R, \quad j = 1, \ldots, C \end{equation} where \$,円\mathrm{mod},円\$ denotes the modulo operation: for \$a,b > 0\$ not necessarily integer, \$\mathrm{mod},円(a,b) = c\$ if and only if \0ドル \leq c < b\$ and \$a = b\cdot k + c\$ with \$k\$ integer.

Note that \0ドル \leq M(i,j) < 1\$.

The matrix \$\mathbf M \$ can be displayed as an image, where the value of each entry determines the color of a pixel, using a colormap to translate numbers between \0ドル\$ and \1ドル\$ into colors. The simplest colormap is to directly consider each number as grey intensity, with \0ドル\$ corresponding to black and \1ドル\$ to white.

As an example, \$R=500\$, \$C=800\$, \$s=0.8\$ with the grey colormap give the following image:

The challenge

Given two positive integers \100ドル \leq R, C \leq 2000 \$ and a number \0ドル < s \leq 1\$, display the above defined matrix \$\mathbf M\$ as an image. You can use any colormap of your choice, not necessarily consistent across images, as long as it satisfies the very lax requirements described next.

Colormap requirements

  1. At least \16ドル\$ different colours.
  2. Reasonably gradual changes between adjacent colours.
  3. The first and last colours should be clearly different.

Although the terms reasonably gradual and clearly different are somewhat subjective, this is not likely to be a contentious point. The sole purpose of these requirements is to prevent abuse. If your programming language offers a default colormap, it is most likely fine. If it doesn't, using grey is probably the shortest option.

Additional rules

  • Graphical output is required, with output being flexible as usual.
  • The image should have the correct orientation, with \$M(1,1)\$ corresponding to the upper-left corner.
  • The image should have the aspect ratio given by \$R\$ and \$C\$. That is, each entry of \$\mathbf M\$ should correspond to a square pixel.
  • If the image is output by displaying it on the screen, it is not necessary that each screen pixel corresponds to an image pixel. That is, the display scaling is flexible (but the aspect ratio should be kept).
  • Auxiliary elements such as axis labels, grid lines or a white frame are not required, but are allowed.
  • Programs or functions are accepted. Standard loopholes are forbidden.
  • Shortest code in bytes wins.

Test cases

Each of the following uses a different colormap, to illustrate some possibilities (and not incidentally to produce lively pictures).

Inputs: R, C, s Output
500, 800, 0.8
600, 1000, 0.7
800, 800, 0.9
500, 900, 1
700, 1200, 0.6
200, 250, 0.3
asked Jul 7, 2021 at 15:44
\$\endgroup\$
13
  • 3
    \$\begingroup\$ I just want to say that the last example output has some very interesting moirés once your eyes stop burning \$\endgroup\$ Commented Jul 7, 2021 at 15:57
  • 1
    \$\begingroup\$ @UnrelatedString Which is precisely why I chose it (the moiré, not the burning) :-D \$\endgroup\$ Commented Jul 7, 2021 at 15:58
  • 1
    \$\begingroup\$ @pxeger I didn't know that, sorry. Go ahead then. Any ouput format that has consensus is fine \$\endgroup\$ Commented Jul 7, 2021 at 16:00
  • 8
    \$\begingroup\$ What part of this did you consider the "meat" of the challenge while writing it? If a matrix is OK, it seems like it boils down to two loops/ranges and the formula j%i^s/r^s verbatim from the post, which does not look like it admits much clever tricks. If the output is PGM then there's a bit more to golf. So, I want to make sure that permitting matrix output doesn't water down your vision for this challenge. \$\endgroup\$ Commented Jul 7, 2021 at 17:15
  • 2
    \$\begingroup\$ @Lynn Graphical output was (is) an important part of the challenge. Just outputting a matrix waters it down, yes. But that doesn't seem to be allowed by the meta post about image formats. Admittedly there are formats that are close to just the matrix, but they have to be accepted \$\endgroup\$ Commented Jul 7, 2021 at 17:57

10 Answers 10

6
\$\begingroup\$

Haskell, 131 bytes

f=fromIntegral
u=unwords.map show
a%b|a>b=(a-b)%b|1<2=a
(r#c)s="P2":u[c,r,99]:[u[round$f j%(f i**s)/f r**s*99|j<-[1..c]]|i<-[1..r]]

Try it online!

(r#c)s returns the lines of a PGM file.

After writing it like this, I learned I could probably just return a matrix of float values but I don't think that's very interesting.

enter image description here

answered Jul 7, 2021 at 17:16
\$\endgroup\$
1
  • \$\begingroup\$ Allowed formats are the ones with consensus here. Outputting just the matrix is not one of thoese formats, I think \$\endgroup\$ Commented Jul 7, 2021 at 17:59
6
\$\begingroup\$

J, 51 bytes

load'viewmat'
1 :'[:viewmat(|~^&u)"0~/&(1+i.)%u^~['

Try it online!

A J adverb, which uses the library function viewmat to do all the heavy lifting -- we merely need to construct the matrix values.

Assuming the adverb has been assigned to f, called like:

500 (0.8 f) 800

500 800 0.8

500 800 0.8

200 250 0.3

200 250 0.3

answered Jul 7, 2021 at 17:36
\$\endgroup\$
4
\$\begingroup\$

Wolfram Language (Mathematica), 39 bytes

sImage@Array[Mod[#2,#^s]&,{##}]/#^s&

Try it online!

Input [s][R, C].

Test cases run in Mathematica

answered Jul 8, 2021 at 4:22
\$\endgroup\$
4
\$\begingroup\$

K (oK) + iKe, 61 bytes

{w::y;h::x;p::pow[;z];,(;gray;+_255*((p 1+!h)!\:/:1+!w)%p w)}

Try it online!

Shortened heavily and made to work with the help of JohnE and coltim at the k tree.

A function which takes input as R, C, s.

answered Jul 8, 2021 at 7:20
\$\endgroup\$
4
\$\begingroup\$

Python 3, (削除) 116 (削除ここまで) (削除) 114 (削除ここまで)118 bytes

-2 thanks to some basic pointers from hyper-neutrino
+4 to correct an off-by-one error, thanks Tipping Octopus

from matplotlib.pylab import*
def M(R,C,s):
 imshow([[j%i**s/R**s for j in range(1,C+1)]for i in range(1,R+1)]);show()

Fairly straightforward, my first code golf attempt so I may be missing something easily golfable. Executes nested list comprehension inside the imshow() to immediately create image. Needs the show() to actually display the image.

700, 1200, 0.6

700, 1200, 0.6

answered Jul 8, 2021 at 2:33
\$\endgroup\$
4
  • 2
    \$\begingroup\$ Welcome to Code Golf Stack Exchange! If you move the import out of the function, you can save a byte for the indentation. Also, you can inline statements within a function by putting them on one line and separating them with semicolons, which saves more indentation. \$\endgroup\$ Commented Jul 8, 2021 at 2:53
  • 1
    \$\begingroup\$ @hyper-neutrino thanks for the tips! I had assumed the import statement needed to be inside the function definition, but it's good that it doesn't! \$\endgroup\$ Commented Jul 8, 2021 at 3:43
  • 2
    \$\begingroup\$ Technically you need range(1,R+1) and range(1,C+1), though that's likely golfable \$\endgroup\$ Commented Jul 8, 2021 at 5:28
  • 1
    \$\begingroup\$ You can golf it a bit more with: def f(R,C,s):imshow([[-~j%i**s/R**s for j in range(C)]for i in range(1,R+1)]);show() \$\endgroup\$ Commented Jul 8, 2021 at 11:19
4
\$\begingroup\$

JavaScript + HTML, 156 bytes

(R,C,s)=>{for((w=x=>document.write(x))`<table cellspacing=0>`,i=0;i++<R;)for(w`<tr>`,j=0;j<C;)w(`<td bgcolor=#${((++j%i**s*16/R**s|0)*273).toString(16)}>`)}
  • -7 bytes by Shaggy

; (function run() {
f=
(R,C,s)=>{for((w=x=>document.write(x))`<table cellspacing=0>`,i=0;i++<R;)for(w`<tr>`,j=0;j<C;)w(`<td bgcolor=#${((++j%i**s*16/R**s|0)*273).toString(16)}>`)}
R = /*R{*/500/*}*/;
C = /*C{*/800/*}*/;
s = /*s{*/0.8/*}*/;
document.write(`
<div style="margin-bottom: 10px;">
 <label> R = <input id="inputR" type="number" step="1" value="${R}" oninput="UpdateJS()" /></label><br />
 <label> C = <input id="inputC" type="number" step="1" value="${C}" oninput="UpdateJS()" /></label><br />
 <label> s = <input id="inputS" type="number" step="0.01" value="${s}" oninput="UpdateJS()" /></label><br />
 <form action="${location.href}" method="post">
 <input id="inputJs" type="hidden" name="js" />
 <input type="hidden" name="css" />
 <input type="hidden" name="html" />
 <input type="hidden" name="console" value="false" />
 <input type="hidden" name="babel" value="false" />
 <button type="submit">Draw</button>
 </form>
</div>
`)
f(R, C, s);
UpdateJS = function () {
 R = inputR.value;
 C = inputC.value;
 s = inputS.value;
 js = `; (${run}());`
 .replace(/\/\*R\{\*\/.*?\/\*\}\*\//, `/*R{*/${R}/*}*/`)
 .replace(/\/\*C\{\*\/.*?\/\*\}\*\//, `/*C{*/${C}/*}*/`)
 .replace(/\/\*s\{\*\/.*?\/\*\}\*\//, `/*s{*/${s}/*}*/`);
 inputJs.value = js;
};
UpdateJS();
}());

answered Jul 8, 2021 at 2:52
\$\endgroup\$
1
  • \$\begingroup\$ 158 bytes \$\endgroup\$ Commented Jul 8, 2021 at 9:08
4
\$\begingroup\$

R, 66 bytes

function(R,C,s)cat('P2',C,R,99,(99*outer(1:C,(1:R)^s,`%%`))%/%R^s)

Try it online!

I kinda think that pajonk's answer is close to the shortest possible using R's built-in graphics... so here's a completely different approach, which actually turns-out to be 4 bytes shorter...

Outputs the contents of a greyscale PGM file. At least on my laptop using Apple's 'Preview' program, the newline characters separating lines appear to be superfluous.

Here's Preview's display of the the output of ploughed_field(500,800,.8):

enter image description here

answered Jul 8, 2021 at 14:06
\$\endgroup\$
4
\$\begingroup\$

Python 3, (削除) 90 (削除ここまで) 73 bytes

from pylab import*;ion()
def M(R,C,s):imshow(-~r_[:C]%c_[1:R+1]**s/R**s)

Heavily based on Danica's answer, I would have commented but I have 0 reputation.

Shorter import statement

ion() to show instead of ;show()

arange (from numpy.arange) array approach for faster performance and fewer bytes

remove def function indent

 from pylab import* 
 ion()
 def M(R,C,s):imshow((arange(C)+1)%(arange(R)+1)[:,None]**s/R**s)

Thanks to ovs this shortens to 74 bytes

And a -~ trick removes 1 byte from r_[1:C+1]

answered Jul 9, 2021 at 10:55
\$\endgroup\$
2
  • 2
    \$\begingroup\$ Welcome to CGCC! numpy has the builtins r_ and c_, which concatenate arrays and slices along different axis. In this case, they can be used to shorten the expression to r_[1:C+1]%c_[1:R+1]**s/R**s \$\endgroup\$ Commented Jul 9, 2021 at 11:20
  • \$\begingroup\$ Thank you for teaching me something new! That is amazing. \$\endgroup\$ Commented Jul 9, 2021 at 11:34
3
\$\begingroup\$

R, (削除) 84 (削除ここまで) 70 bytes

-14 bytes thanks to @Dominic

function(R,C,s)image(outer(1:C,(R:1)^s,`%%`)/R^s,c=rainbow(64),as=R/C)

Try it online!

Try it on rdrr.io with graphical output

answered Jul 8, 2021 at 7:21
\$\endgroup\$
4
  • 1
    \$\begingroup\$ 70 bytes... \$\endgroup\$ Commented Jul 8, 2021 at 9:49
  • \$\begingroup\$ (or an even more brightly-coloured version for 69 bytes - unless there are possible inputs with R<16 but that still need ≥16 colours)... \$\endgroup\$ Commented Jul 8, 2021 at 10:00
  • \$\begingroup\$ Hm. Please ignore the 69-byter: there are lots of possible inputs with R<16 that need many more colours... \$\endgroup\$ Commented Jul 8, 2021 at 10:12
  • 1
    \$\begingroup\$ 66 bytes but I posted this one myself! \$\endgroup\$ Commented Jul 8, 2021 at 14:09
2
\$\begingroup\$

Red, 137 bytes

func[r c s][i: make image! to[]as-pair c r k: 0
repeat y r[repeat x c[i/(k: k + 1): to 1.1.1 to[](to 1 x %(y ** s)/(r ** s)* 255)]]?(i)]	

f 500 800 0.8

enter image description here

answered Jul 8, 2021 at 12:34
\$\endgroup\$
2
  • 3
    \$\begingroup\$ Very appropriate colormap for a Red answer :-D \$\endgroup\$ Commented Jul 8, 2021 at 14:51
  • \$\begingroup\$ @LuisMendo Indeed :) \$\endgroup\$ Commented Jul 8, 2021 at 18:07

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.