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
- At least \16ドル\$ different colours.
- Reasonably gradual changes between adjacent colours.
- 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 |
10 Answers 10
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]]
(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.
-
\$\begingroup\$ Allowed formats are the ones with consensus here. Outputting just the matrix is not one of thoese formats, I think \$\endgroup\$Luis Mendo– Luis Mendo2021年07月07日 17:59:17 +00:00Commented Jul 7, 2021 at 17:59
J, 51 bytes
load'viewmat'
1 :'[:viewmat(|~^&u)"0~/&(1+i.)%u^~['
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
200 250 0.3
K (oK) + iKe, 61 bytes
{w::y;h::x;p::pow[;z];,(;gray;+_255*((p 1+!h)!\:/:1+!w)%p w)}
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.
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
-
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\$2021年07月08日 02:53:56 +00:00Commented 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\$Danica Scott– Danica Scott2021年07月08日 03:43:05 +00:00Commented Jul 8, 2021 at 3:43
-
2\$\begingroup\$ Technically you need
range(1,R+1)andrange(1,C+1), though that's likely golfable \$\endgroup\$Tipping Octopus– Tipping Octopus2021年07月08日 05:28:28 +00:00Commented 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\$Noodle9– Noodle92021年07月08日 11:19:04 +00:00Commented Jul 8, 2021 at 11:19
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();
}());
R, 66 bytes
function(R,C,s)cat('P2',C,R,99,(99*outer(1:C,(1:R)^s,`%%`))%/%R^s)
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):
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]
-
2
-
\$\begingroup\$ Thank you for teaching me something new! That is amazing. \$\endgroup\$Alwin– Alwin2021年07月09日 11:34:08 +00:00Commented Jul 9, 2021 at 11:34
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)
-
1\$\begingroup\$ 70 bytes... \$\endgroup\$Dominic van Essen– Dominic van Essen2021年07月08日 09:49:07 +00:00Commented 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\$Dominic van Essen– Dominic van Essen2021年07月08日 10:00:49 +00:00Commented 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\$Dominic van Essen– Dominic van Essen2021年07月08日 10:12:58 +00:00Commented Jul 8, 2021 at 10:12
-
1\$\begingroup\$ 66 bytes but I posted this one myself! \$\endgroup\$Dominic van Essen– Dominic van Essen2021年07月08日 14:09:56 +00:00Commented Jul 8, 2021 at 14:09
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
-
3\$\begingroup\$ Very appropriate colormap for a Red answer :-D \$\endgroup\$Luis Mendo– Luis Mendo2021年07月08日 14:51:49 +00:00Commented Jul 8, 2021 at 14:51
-
\$\begingroup\$ @LuisMendo Indeed :) \$\endgroup\$Galen Ivanov– Galen Ivanov2021年07月08日 18:07:47 +00:00Commented Jul 8, 2021 at 18:07
Explore related questions
See similar questions with these tags.
j%i^s/r^sverbatim 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\$