g | x | w | all
Bytes Lang Time Link
044Wolfram Language Mathematica190730T084058Zatt
056AWK241129T181811Zxrs
019Japt R180910T140742ZShaggy
053Python 3241012T002304Zaeh5040
026Uiua241010T235436Znoodle p
013Vyxal241010T222357Zemanresu
027Zsh240121T170526Zpxeger
015Vyxal j210607T110733ZWasif
051Haskell171016T131605ZLaikoni
039ink190731T003638ZSara J
058Underload190729T210554ZEdgyNerd
050Ruby171016T211634Zanna328p
057Wolfram Language Mathematica190729T185721ZRoman
015Stax190729T182108Zrecursiv
054TSQL171016T191126ZBradC
061Dart181119T084104ZElcan
018MathGolf181116T150014Zmaxb
078JavaScript181119T022817Zeeze
052ed181116T034122Zuser3604
069Python 3181116T155719ZHenry T
029Burlesque181116T112703Zmroman
024Pyth181116T083842ZSok
050R171016T132415ZGiuseppe
028Pyth171016T181146ZMr. Xcod
993Shakespeare Programming Language180909T192515ZJosiahRy
015Jelly171016T132823ZErik the
044PowerShell171017T151719ZAdmBorkB
066C gcc171111T132041Zgastropn
064C171231T040903Zl4m2
049Haskell171231T000741Ztotallyh
028Vim171030T175343ZBlackCap
054Haskell171017T032113Zaddison
033Perl 5171016T140703ZDom Hast
036bash171016T150525ZNahuel F
041K oK171026T144219Zmkst
055Octave171016T143027ZStewie G
0486502 machine code C64171019T095625ZFelix Pa
025Vim171016T193034ZH.PWiz
052Bash171018T074235Zdessert
047Jq 1.5171018T082828Zjq170727
050Javascript171016T150954ZBrian H.
076C gcc171016T132826ZSteadybo
032Retina171016T131546ZMartin E
055Java 8171016T133400ZKevin Cr
035///171017T071722Zsteenber
038ReRegex171017T033457ZATaco
014Husk171017T024559ZLeo
035APL Dyalog171016T132600ZUriel
039J171016T180442ZFrownyFr
071Haxe171016T192727ZAurel B&
078IBM/Lotus Notes Formula171016T145431ZElPedro
047PHP171016T184358ZTitus
052Python 2171016T133455ZRod
066Batch171016T173026ZNeil
025V171016T155714ZDJMcMayh
078Batch171016T154601Zschnaade
052Haskell171016T153558Znimi
032Retina171016T142247ZNeil
054C# .NET Core171016T151152Zthe defa
nan171016T141445ZBrad Gil
025CJam171016T140247ZPeter Ta
01205AB1E171016T133055ZEmigna

Wolfram Language (Mathematica), 46 44 bytes

Outer[Print[#,a=nown," ",#2,a,s]&,b=k|unk,b]

Try it online!

AWK, 56 bytes

{$0="X Xs\nX unXs\nunX Xs\nunX unXs";gsub("X","known")}1

To test:

awk '{$0="X Xs\nX unXs\nunX Xs\nunX unXs";gsub("X","known")}1' <<< ""

Japt -R, 22 19 bytes

`kÍ5 unkÍ5`¸ï ˸+'s

Test it

`...`¸ï ˸+'s
`...`             :Compressed string "known unknown"
     ¸            :Split on spaces
      ï           :Cartesian product
        Ë         :Map
         ¸        :  Join with space
          +'s     :  Append "s"
                  :Implicit output joined with newlines

Python 3, 53 bytes

for n in 2,3,5,0:u='unknowns';print(u[n&2:7],u[n%3:])

Try it online!

Uiua, 26 bytes

♭⊞⍚$"_ _s".{⤙⊂"un""known"}

Try it: Uiua pad

   {⤙⊂"un""known"}
{"known" "unknown"}

   ⊞⊟.{⤙⊂"un""known"}              # Here, using `⊟ couple` as the function
╭─                                 # to `⊞ table`, for demonstration purposes.
╷ ⌜known⌟   ⌜known⌟    
╷ ⌜known⌟   ⌜unknown⌟  
                       
  ⌜unknown⌟ ⌜known⌟    
  ⌜unknown⌟ ⌜unknown⌟  
                      ╯

   ⊞⍚$"_ _s".{⤙⊂"un""known"}       # $"_ _s" is a format string. Each _ is
╭─                                 # replaced by the corresponding word.
╷ ⌜known knowns⌟   ⌜known unknowns⌟    
  ⌜unknown knowns⌟ ⌜unknown unknowns⌟  
                                      ╯

   ♭⊞⍚$"_ _s".{⤙⊂"un""known"}      # ♭ flattens the array of boxes.
{"known knowns" "known unknowns" "unknown knowns" "unknown unknowns"}

Vyxal, 13 bytes

‛»²‛¢λ":\s+Ẋ⁋

Try it Online!

      "       # Pair
‛»²           # "known"
   ‛¢λ        # and "unknown"
           Ẋ  # Cartesian product with
       :      # A copy
        \s+   # with "s" appended to each
            ⁋ # Join by newlines, joining each row by spaces

Zsh, 27 bytes

>{,un}known\ {,un}knowns
ls

Attempt This Online!

Or, a slightly cheaty version which outputs to a file called known knowns:

Zsh, 26 bytes

ls>{,un}known\ {,un}knowns

Attempt This Online!

Vyxal j, 15 bytes, (@lyxal)

`»² ¢λ`⌈:ẊvṄ\s+

Try it Online!

Vyxal j, 18 bytes

`»²`:‛unp":\svpẊvṄ

Try it Online!

Vyxal has really improved my productivity, I wrote this in just 2 minutes.

`»²`    Dictionary compressed string "known"
:         Duplicate ^
‛un     Two byte string `un`
p         Prepend un to known    
"          Pair the two words as a list
:          Duplicate ^
\s       Single byte char "s"
vp       Vectorised append to the duplicated lost
Ẋ         Take cartesian product of two lists
vṄ      Vectorised join by space in each ordered pair of the ^
            (Implicit join with newlines, by j flag)

Haskell, 60 58 53 51 bytes

f<$>l<*>l
f x y=x++' ':y++"s"
l=["known","unknown"]

Try it online!

Yields a list of lines as was recently allowed. Thanks to @firefrorefiddle for pointing out.

-2 bytes thanks to cole.


58 byte version:

f=<<"? ?s\n? un?s\nun? ?s\nun? un?s"
f '?'="known"
f c=[c]

Try it online! Yields a single string.

ink, 39 bytes

-(i){||un}known {&|un}knowns
{i<10:->i}

Try it online!

Underload, 58 bytes

((:^)(s
)( )(known):(un)~*):^!:S~SSS^~S~SSS^S~SSS^~!:S~SSS

Uses a simple lookup table with a lot of Ss.

Try it Online!

Ruby, 53 50 bytes

$><<"a as
a unas
una as
una unas".gsub(?a,"known")

Wolfram Language (Mathematica), 57 bytes

StringReplace["K Ks
K unKs
unK Ks
unK unKs","K"->"known"]

Try it online!

Stax, 15 bytes

┬τj%7↕▬α0▄╘δ₧▲\

Run and debug it

T-SQL, 56 54 bytes

PRINT REPLACE('1 1s
1 un1s
un1 1s
un1 un1s',1,'known')

SQL supports line breaks inside string literals, so similar to some other languages already posted.

EDIT: Slightly longer (82 bytes), but a bit more clever:

SELECT k+s+k+p+k+s+u+p+u+s+k+p+u+s+u+p
FROM(SELECT'known'k,' 's,'unknown'u,'s
'p)t

EDIT 2: My favorite so far, using a cross-self-join from a derived table (79 bytes):

WITH t AS(SELECT'known'a UNION SELECT'unknown')
SELECT z.a+' '+t.a+'s'FROM t,t z

EDIT 3: Changed the replacement character from 'x' to 1, which lets me remove the quotes around it and save 2 bytes, since REPLACE does an implicit conversion to string.

Dart, 62 61 bytes

g({s='known'})=>"$s $s\s\n$s un$s\s\nun$s $s\s\nun$s un$s\s";

Try it online!

MathGolf, 23 19 18 bytes

4♀*(╦_╢Ñ▌]■{ u's+p

Try it online!

Explanation

I really need some base-250 integers

4♀*(                 Push 4, push 100, multiply, decrement (resulting in 399)
    ╦                Fetch dictionary word with index 399
     _               Duplicate
      ╢Ñ             Push "un"
        ▌            Prepend to TOS
         ]           Wrap stack in array
          ■          Cartesian product with itself
           {         For-each
             u       Join with space (space character is before the "u")
              's+    Add "s"
                 p   Print

JavaScript, 78 bytes

This is my first-ever attempt at solving a code golf, so all suggestions welcome!

console.log(k=(u="unknown").substr(2),k+(s="s")+(n="\n")+k,u+s+n+u,k+s+n+u,u+s)

Explanation

Step 1: k=(u="unknown").substr(2). The u="unknown" evaluates to "unknown". A substring of this, from char #2 until the end of the string, is then assigned to variable k. This whole thing evaulutes to the outermost assignment, "known", which is the first parameter to console.log.

Step 2: Next is a ,. Each parameter to console.log is printed with a space in between, so a , represents a space in the output. The current output is "known ".

Step 3: k+(s="s") evalutates to "knowns", and at the same time assigns "s" to the variable s, to be used as a shorthand for later. The current output is "known knowns"

Step 4: +(n="\n")+k. We append a newline to this, and store the newline character as a shorthand for later. We also append k. The current output is "known knowns{newline}known".

Step 5: ,u+s+n+u,k+s+n+u,u+s) the rest is very simple: just appending k, s, and u, using ,s for spaces, to spell out the rest of the output.

Like I said, this is my first-ever code golf, so I would appreciate any tips/tricks.

ed, 52 bytes

a
known knowns
.
,t1
2s/ k/ unk/
,t2
3,4s/^k/unk/
w

Try it online!

Python 3, 69 bytes

k=['known','unknown']
for i in range(4):print(k[i//2]+' '+k[i%2]+'s')

Burlesque - 29 bytes

"unknown"J2.-CLJcp{wd's_+}muQ

"unknown"J                     duplicate
          2.-                  drop 2
             CL                collect stack
               J               duplicate
                cp             cross product
                  {            begin block
                   wd          words
                     's_+      append `s`
                         }     end block
                          mu   map unlines
                            Q  pretty print

Try it online.

Alternate versions:

"known unknown"wdJcp{wd's_+}muQ

Pyth, 24 bytes

jm+j;d\s^_>B"unknown"2 2

Try it online here.

jm+j;d\s^_>B"unknown"2 2   
            "unknown"      String literal
          >          2     Remove the first two letters
           B               Pair the above with the original string - ["unknown", "known"]
         _                 Reverse
        ^              2   Cartesian product with itself
 m                         Map each pair, as d, using:
   j;d                       Join on spaces
  +   \s                     Append "s"
j                          Join on newlines, implicit print

R, 52 51 50 bytes

cat(gsub(1,"known","1 1s
1 un1s
un1 1s
un1 un1s"))

Try it online!

Surprisingly short substitution and print commands make this an actually competitive R answer in a challenge!

Even if it's super boring. Mildly more interesting now, and with a byte saved thanks to J.Doe!

Saved another byte thanks to this answer, also by J.Doe!

Pyth, 28 bytes

-1 byte thanks to hakr14.

jm+j;d\s^_c"unknown known"d2

Try it here!

Shakespeare Programming Language, 1021 1012 993 bytes

-19 bytes thanks to Joe King!

,.Ajax,.Ford,.Page,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:Am I nicer a big cat?If sois the remainder of the quotient betweenI the sum ofa cat a big cat worse a big cat?If notlet usScene V.You be the sum ofa fat fat fat pig the cube ofthe sum ofa cat a big big cat.Speak thy.You be the sum ofyou the sum ofa cat a fat fat fat pig.Speak thy.Scene V:.[Exit Ajax][Enter Page]Page:You be the product ofthe sum ofa cat a big big cat the sum ofa pig a big big big big cat.Speak thy.You be the sum ofyou the sum ofa cat a big cat.Speak thy.Ford:You be the sum ofI a cat.Speak thy.You be the sum ofyou a big big big cat.Speak thy.Page:Speak thy.You be the sum ofyou the sum ofa cat a big big cat.Is the remainder of the quotient betweenAjax a big cat worse a cat?If soyou big big big big big cat.Speak thy.If solet usScene X.You be twice the sum ofa cat a big big cat.Speak thy.Scene X:.[Exit Page][Enter Ajax]Ford:You be the sum ofyou a cat.Be you worse a big big big cat?If solet usAct I.

Try it online!

Jelly, 15 bytes

“ṿ1“ŒwƘ»pż€⁾ sY

Try it online!

PowerShell, 46 44 bytes

' s
 uns
un s
un uns'-replace' |s','known$&'

Try it online!

(Almost) simple string replacement. Uses Neil's approach to trim two bytes. Thanks to Martin for pointing that out.

Sadly, it's shorter than the more interesting cross-product method by three five three bytes:

PowerShell, 49 47 bytes

($a='known','unknown')|%{$i=$_;$a|%{"$i $_`s"}}

Try it online!

C (gcc), 70 66 bytes

Thanks to @l4m2 for -4 bytes!

f(i){for(i=8;i--;)printf("unknown%s"+(i>4|i==2)*2,i%2?" ":"s\n");}

Try it online!

C, gcc, 64 bytes

c="unknown";f(i){for(i=4;i--;)printf("%s %ss\n",i&2|c,i%2*2+c);}

Seems doesn't work on TIO, but works fine on my coputer

Haskell, 49 bytes

unwords<$>mapM(\s->[s,"un"++s])["known","knowns"]

Try it online!

Vim, 28 keystrokes

iknown <C-n>s<CR><C-X><C-l><S-Left>un<Esc>o<C-p><Left> <C-n><Esc>o<C-p><C-p> <C-p>s

Also 28:

iknown <C-n>s<Esc>qqo<C-X><C-l><S-Left>un<Esc>qo<C-p><Left> <C-n><Esc>@q

Haskell, 71 66 56 54 bytes

(<*>).map((++).init)<*>map(' ':)$["knowns","unknowns"]

Thanks to @Leo for -3 bytes!

Note: In the question's comments, the o.p. said that returning a list of strings is okay

Try it here.

Perl 5, 33 bytes

Disclaimer: I didn't realise that brace expansion was possible within the <...> operator (learned thanks to @Grimy's answer!) and the using the clever expansion trick from @NahuelFouilleul's amazing bash answer, I was able to build this solution. I will happily remove this at either of their request.

print<"{,un}known {,un}knowns$/">

Try it online!


Perl 5, 42 bytes

41 bytes code + 1 for -p.

s//K Ks
K unKs/;s/K/known/g;$\=s/^/un/gmr

Try it online!


Perl 5, 45 bytes

Tried to come up with an alternative, but couldn't make it shorter... Thought it was different enough to warrant adding anyway.

print"un"x/[3467]/,known,$_%2?"s
":$"for 0..7

Try it online!

bash, 36 bytes

printf %s\\n {,un}known\ {,un}knowns

other solutions

36

eval echo\ {,un}known\ {,un}knowns\;

37

eval printf '%s\\n' \{,un}known{\\,s}

38

eval eval echo\\ \{,un}known{\\,'s\;'}

41

x=\\\ {,un}known;eval "eval echo$x$x\s\;"

45

x='\ {,un}known' e=eval;$e "$e echo$x$x\s\;"
x='\ {,un}known' e=eval\ ;$e"$e\echo$x$x\s\;"

if leading newline and extra space were accepted 31 bytes :

echo '
'{,un}known\ {,un}knowns

K (oK), 41 bytes

Solution:

(1_',/x,/:\:x:(" known";" unknown")),'"s"

Try it online!

Explanation:

This still feels clunky, but this is the shortest version yet:

(1_',/x,/:\:x:(" known";" unknown")),'"s" / the solution
(                                  ),'"s" / append "s" to each left
              (" known";" unknown")       / 2-item list of " known" and " unknown"
            x:                            / save as variable x
      x,/:\:                              / x concatenate each right (/:) with each left (\:)
    ,/                                    / flatten lists
 1_'                                      / drop first item from each list (ie drop the leading whitespace)

Notes:

Other versions:

/ 49 bytes, just join each right/each left and flatten
,/("known";"unknown"),/:\:(" knowns";" unknowns") 

/ 43 bytes, try to be smarter building the known/knowns
,/2 0_/:\:"unknown ",/:("";"un"),\:"knowns"

Octave, 55 bytes

[{'un','known',[115,10],32}{'bdbcbdabcabdbcabdabc'-96}]

Try it online!

Explanation:

First, we create a cell array with four strings: un, known, s\n and . Then we create a string bdbcbdabcabdbcabdabc that becomes the appropriate indices when we subtract 96: a=1, b=2, c=3, d=4. We index the cell array using cell indexing {}, and concatenate the result using brackets [].


The following is one byte longer than the output itself.

printf(strrep(', ,s\n, un,s\nun, ,s\nun, un,s',',','known'))

6502 machine code (C64), 48 bytes

00 C0 A9 37 85 FB A9 73 4D 2B C0 8D 2B C0 A9 0D 4D 2C C0 8D 2C C0 A9 26 90 02
E9 02 A0 C0 20 1E AB 06 FB D0 E1 60 55 4E 4B 4E 4F 57 4E 53 0D 00

Online demo

Usage: sys49152


How it works

The trick here is to use a "loop counter" for 8 iterations where bits 7 to 1 of the initial value are 1 for unknown(s) and 0 for known(s) in one iteration. This counter is shifted to the left after each iteration (shifting the leftmost bit into the carry flag) and bit 0 is initially 1 so we know we're finished once the last bit was shifted out. In the first iteration, known is printed because when calling the program, the carry flag is clear.

In each iteration, the end of the string is toggled between <space> and s<newline>.

Here's the commented disassembly listing:

         00 C0            .WORD $C000    ; load address
.C:c000  A9 37            LDA #$37       ; initialize loop counter ...
.C:c002  85 FB            STA $FB        ; ... as 0011 0111, see description
.C:c004   .loop:
.C:c004  A9 73            LDA #('s'^' ') ; toggle between 's' and space
.C:c006  4D 2B C0         EOR .plural
.C:c009  8D 2B C0         STA .plural
.C:c00c  A9 0D            LDA #$0D       ; toggle between newline and 0
.C:c00e  4D 2C C0         EOR .newline
.C:c011  8D 2C C0         STA .newline
.C:c014  A9 26            LDA #<.knowns  ; start at "known" except
.C:c016  90 02            BCC .noprefix  ; when carry set from shifting $fb:
.C:c018  E9 02            SBC #$02       ; than start at "un"
.C:c01a   .noprefix:
.C:c01a  A0 C0            LDY #>.knowns  ; high-byte of string start
.C:c01c  20 1E AB         JSR $AB1E      ; output 0-terminated string
.C:c01f  06 FB            ASL $FB        ; shift loop counter
.C:c021  D0 E1            BNE .loop      ; repeat if not 0 yet
.C:c023  60               RTS            ; done
.C:c024   .unknowns:
.C:c024  55 4E           .BYTE "un"
.C:c026   .knowns:
.C:c026  4B 4E 4F 57 4E  .BYTE "known"
.C:c02b   .plural:
.C:c02b  53              .BYTE "s"
.C:c02c   .newline
.C:c02c  0D 00           .BYTE $0d, $00

Vim 28 25 bytes

This is my first Vim answer, any golfing tips are welcome.

2iunknown ␛rsY3P2xw.+.jw.

In action

Thank you Lynn for writing the python script to make that fantastic animation.

This can also be run by V Try it Online!

Also 25:

2iknown ␛rsY3pwiun␛+.+.w.

Bash, 60 57 54 52 bytes

b=${a=known}s;echo "$a $b
$a un$b
un$a $b
un$a un$b"

Try it online!

Thank you guys!

Jq 1.5, 47 bytes

"K Ks
K unKs
unK Ks
unK unKs"|gsub("K";"known")

Try it online!

Javascript 66 54 53 50 bytes

_=>` s
 uns
un s
un uns`.replace(/ |s/g,'known$&')

History

C (gcc),  79  78 76 bytes

Thanks to @Justin Mariner for golfing one byte!

f(){printf("%s %1$ss\n%1$s un%1$ss\nun%1$s %1$ss\nun%1$s un%1$ss","known");}

Try it online!

Retina, 33 32 bytes

Saved 1 byte using an intermediate printing approach from Leo.


 ¶u

knowns
u
 un
:`s 
 
m`^
un

Try it online!

Explanation


 ¶u

Turns the non-existent (i.e. empty) input into the string on the second line. That one seems pretty weird, but these characters are codes for the stuff that goes between two instances of known[s] on the first two lines of the result. Space and linefeed are just themselves and u is un.


knowns

Now we insert knowns at every position (i.e. at the beginning, end, and between every pair of characters).

u
 un

We decode the u.

:s 
 

Then we get rid of the ss in front of spaces, i.e. those in the first half of each line, and print the result.

m`^
un

And finally we prepend un to both lines and print the result again.

This beats the trivial approach of just using a placeholder for known by 4 bytes, but not Neil's more efficient implementation of that approach.

Java 8, 56 55 bytes

v->" s\n uns\nun s\nun uns".replaceAll(" |s","known$0")

-1 byte thanks to @SuperChafouin.

Explanation:

Try it here.

v->                         // Method with empty unused parameter
  " s\n uns\nun s\nun uns"  //  Literal String
   .replaceAll(" |s",       //  Replace all spaces and "s" with:
     "known                 //   Literal "known"
           $0")             //   + the match (the space or "s")
                            // End of method (implicit / single-line return-statement)

///, 35 bytes

/2/un1//1/known/1 1s
1 2s
2 1s
2 2s

Try it online!

ReRegex, 38 bytes

a/known/a as\na unas\nuna as\nuna unas

Try it online!

Husk, 14 bytes

OΠṠemhw¨ṅW∫ḟωμ

Try it online!

Explanation

OΠṠemhw¨ṅW∫ḟωμ
       ¨ṅW∫ḟωμ    The compressed string "knowns unknowns"
      w           Split on spaces ["knowns","unknowns"]
   e              Make a list with:
    mh             this list with the last letter dropped from each word
  Ṡ                and this same list
                  [["known","unknown"],["knowns","unknowns"]]
 Π                Cartesian product [["known","knowns"],["unknown","knowns"],["known","unknowns"],["unknown","unknowns"]]
O                 Sort the list [["known","knowns"],["known","unknowns"],["unknown","knowns"],["unknown","unknowns"]]
                  Implicitely print joining with spaces and newlines

APL (Dyalog), 64 47 35 bytes

⍪,∘.{⍺,' ',⍵,'s'}⍨k('un',k←'known')

Try it online!

How?

k←'known' - k is "known"

k('un',k←'known') - "known" "unknown"

∘.... - outer product with itself

    {⍺,' ',⍵,'s'} - with the function that formats the args as {⍺} {⍵}s

, - smash the product table into vector

- separate to columns

J, 39 bytes

echo@;@,"1//' s'|.@;"0/(;'un',])'known'

Try it online!

Here's another one, that I'll explain instead (53 chars):

;"1((<<<2)&{,],48&A.,:n)({.,' ';n=.'un';])'known';'s'

|

                        ({.,' ';n=.'un';])'known';'s'

Yields ["known", " ", "un", "known", "s"] and defines n that adds "un" in front. Then for each of the 4 lines respectively we

    (<<<2)&{                     Remove "un", the 2nd string
             ]                   Do nothing
               48&A.             Move "un" to the front
                      n          Add "un"
;"1                              Smash the lines.

2,0,1,3,4 is #48 in the alphabetically sorted list of permutations of 0,1,2,3,4. I've no idea how it's implemented.

Haxe, 71 bytes

(?x)->[for(a in x=["","un"])for(b in x)a+'known ${b}knowns'].join("\n")

Try it online!

IBM/Lotus Notes Formula, 78 bytes

@ReplaceSubstring("a as,a bas,ba as,ba bas";"a":"b":",";"known":"un":@Newline)

Not the shortest but actually shorter than just hard coding the strings in @Formula.

Formula language allows lists as the from and to parameters to @ReplaceSubstring. Just a shame that @ReplaceSubstring itself costs 17 bytes and @Newline costs 4 more than "\n".

PHP, 55 51 47 bytes

<?=strtr("1 1s
1 01s
01 1s
01 01s",[un,known]);

try it online

Python 2, 54 52 bytes

-2 bytes thanks to xnor

k='unknowns'
for i in 8,6,2,0:print k[i/3:7],k[i%3:]

Try it online!

The results from the / and % will be [[2, 2], [2, 0], [0, 2], [0, 0]] that will be the starting indexes, removing the un when 2, keeping the string unaltered when 0

Batch, 66 bytes

@set s= in (known unknown)do @
@for %%a%s%for %%b%s%echo %%a %%bs

Alternative answer, also 66 bytes:

@for %%a in (k unk)do @for %%b in (k unk) do @echo %%anown %%bnowns

V, 25 bytes

Two solutions, both 25 bytes

2iunknowns |exÄwxxäj2xj.

Try it online!

Hexdump:

00000000: 3269 756e 6b6e 6f77 6e73 201b 7c65 78c4  2iunknowns .|ex.
00000010: 7778 78e4 6a32 786a 2e                   wxx.j2xj.

And

2iunknown Äwxxäj2xj.Î$rs

Try it online!

Hexdump:

00000000: 3269 756e 6b6e 6f77 6e20 1bc4 7778 78e4  2iunknown ..wxx.
00000010: 6a32 786a 2ece 2472 73                   j2xj..$rs

Batch, 78 bytes

@set a=known
@echo %a% %a%s&echo %a% un%a%s&echo un%a% %a%s&echo un%a% un%a%s

Quite hard to golf, everything non-trivial I tried so far just makes it longer.

Haskell, 57 52 bytes

id=<<id=<<mapM(\s->[s,"un"++s])["known ","knowns\n"]

Try it online!

Retina, 33 32 bytes


 s¶ uns¶un s¶un uns
 |s
known$&

Try it online! Edit: Saved 1 byte thanks to @ovs. Explanation: This is almost the trivial approach of using a placeholder for known, except here I simply insert it before each space or s, which saves 3 4 bytes.

C# (.NET Core), 54 bytes

v=>@"z zs
z unzs
unz zs
unz unzs".Replace("z","known")

Try it online!

Perl 6, 45 bytes

$_='known';.say for [X](($_,"un$_")xx 2)X~'s'

Try it

Expanded

$_ = 'known';

.say                # print with trailing newline the value in topic variable 「$_」

  for               # do that for each of the following

    [X](
      ($_, "un$_")  # ('known','unknown')
        xx 2        # list repeated twice
    ) X~ 's'        # cross using &infix:«~» with 's' (adds 「s」 to the end)

The [X](…) part generates

(("known","known"),("known","unknown"),("unknown","known"),("unknown","unknown")).Seq

Then using X~ on it coerces the inner lists into a Str (because of the &infix:«~» operator), which doing so adds a space between values.

("known known", "known unknown", "unknown known", "unknown unknown").Seq

Then each is joined with an s

("known knowns", "known unknowns", "unknown knowns", "unknown unknowns").Seq

CJam (26 25 bytes)

"unknown"_2>\]2m*{S*'sN}%

Online demo

Cartesian product of ["known" "unknown"] with itself, then each element joined with space and suffixed with s and a newline.

Thanks to Erik for a one-byte saving.

05AB1E, 13 12 bytes

Saved 1 byte thanks to Erik the Outgolfer (avoid closing string)

„Š¢—‚#D's«â»

Try it online!

Explanation

„Š¢—‚           # push the string "known unknown"
     #          # split on spaces
      D         # duplicate
       's«      # append "s" to each
          â     # cartesian product
           »    # join on newline