User avatar
John_Spikowski
Posts: 1614
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: Liberation through Computer Literacy

Wed Nov 13, 2019 2:29 am

If you're running ScriptBasic with scriba only, here is how to use an extension module without having to create a config file and set an environmental variable.

1, Download/unzip the attach ta.so extension module to where you like.

2. Modify the the posted tatamix.sb script to use a full path and attribute in the LIB string.

3. time ./scriba tatamix.sb 200

Code: Select all

DECLARE SUB do_v    ALIAS "do_v"    LIB "/home/pi/sbrt/examples/ta.so"
DECLARE SUB find_s  ALIAS "find_s"  LIB "/home/pi/sbrt/examples/ta.so"
My ta.so is in the examples directory where tatamix.sb resides.
Attachments
scriba.zip
(150.42 KiB) Downloaded 21 times
ta.so.zip
(1.89 KiB) Downloaded 20 times

gkreidl
Posts: 6355
Joined: Thu Jan 26, 2012 1:07 pm
Location: Germany

Re: Liberation through Computer Literacy

Wed Nov 13, 2019 9:43 am

Some people have been asking for a Python implementation of the Tatami challenge. I wasn't really interested for a number of reasons but finally got caught nevertheless. But I wanted a version that is more versatile (being able to find solutions for larger values of s) and while working on it I found an optimization which should be applicable to most other implementations as well.

Both versions I provide (tatami.py and tatami_opt.py) may take up to two arguments: s and nMax. So it's possible to play arround with different values. The current algorithm will break with nMax >= 147026880, because the stored values may be bigger than 255. So the program uses bytearrays, Python list or arrays from the array module (as a last resort, because it is the slowest), depending on the size of nMax, maximum size of Python lists and memory usage. Here is the standard version (tatami.py):

Code: Select all

#!/usr/bin/python3
import sys
from math import sqrt

def tatami(s):
    for i in range(7,nMaxSqrt,2):
        k2 = i + 3
        k3 = i + i - 4
        while ((k2 <= k3) and ((i * k2) < nMax)):
            k4 = (nMax-1) // i
            if k3 < k4:
                k4 = k3
            for j in range(k2,k4+1,2):
                v[i*j] += 1
            k2 += i+1
            k3 += i-1
    for i in range(8,nMaxSqrt,2):
        k2 = i + 3
        k3 = i + i - 4
        while ((k2 <= k3) and ((i * k2) < nMax)):
            k4 = (nMax-1) // i
            if k3 < k4:
                k4 = k3
            for j in range(k2,k4+1):
                v[i*j] += 1
            k2 += i + 1
            k3 += i - 1
    try:
        return v.index(s)
    except:
        return -1

s = 200
nMax = 100000000

if len(sys.argv) > 1:
    try:
        s = int(sys.argv[1])
    except:
        pass
if len(sys.argv) > 2:
    try:
        nMax = int(sys.argv[2])
    except:
        pass

if (nMax & 1) != 0:
    nMax += -1
              
if nMax > 536870912 and sys.maxsize == 2147483647:
    try:
        from array import array
        v = array('I',[0])*nMax
    except:
        print("Not enough memory!")
        sys.exit(0)
elif nMax >= 147026880:
    try:
        v = [0]*nMax
    except:
        try:
            from array import array
            v = array('I',[0])*nMax
        except:
            print("Not enough memory!")
            sys.exit(0)
else:
    v = bytearray(nMax)

nMaxSqrt = int(sqrt(nMax))

res = tatami(s)
if res > -1:
    print("The smallest room size s for which T(s) = "+str(s)+" is "+str(res))
else:
    print("No solution found for s=" +str(s)+" and nMax="+str(nMax))
    maxs = 0
    maxi = 0
    for i in range(0,nMax):
        if v[i] > maxs:
            maxs = v[i]
            maxi = i
    print("Maximal T(s) found = "+str(maxs)+" for room size = "+str(maxi))
Of course it will run much slower than a C version.:

Code: Select all

time ./tatami.py
The smallest room size s for which T(s) = 200 is 85765680

real	1m29,730s
user	1m29,230s
sys	0m0,240s
But it will give a nice performance time when run from pypy3:

Code: Select all

time pypy3 ./tatami.py
The smallest room size s for which T(s) = 200 is 85765680

real	0m16,484s
user	0m16,034s
sys	0m0,430s
The optimization takes into account, that only even room sizes are allowed. Half of the size of the v-Array is never used. So it's possible to reduce the dimension of the v-array to nMax/2. It needs an additional shift by one to the right within the tatami function: v[(i*j) >> 1] += 1. The result has to be multiplied by 2 in the end. The overhead should be small and the search time for the result will be reduced. Here's the code of the optimized Python version (tatami_opt.py):

Code: Select all

#!/usr/bin/python3
import sys
from math import sqrt

def tatami(s):
    for i in range(7,nMaxSqrt,2):
        k2 = i + 3
        k3 = i + i - 4
        while ((k2 <= k3) and ((i * k2) < nMax)):
            k4 = (nMax-1) // i
            if k3 < k4:
                k4 = k3
            for j in range(k2,k4+1,2):
                v[(i*j) >> 1] += 1
            k2 += i+1
            k3 += i-1
    for i in range(8,nMaxSqrt,2):
        k2 = i + 3
        k3 = i + i - 4
        while ((k2 <= k3) and ((i * k2) < nMax)):
            k4 = (nMax-1) // i
            if k3 < k4:
                k4 = k3
            for j in range(k2,k4+1):
                v[(i*j) >> 1] += 1
            k2 += i + 1
            k3 += i - 1
    try:
        return v.index(s)
    except:
        return -1

s = 200
nMax = 100000000

if len(sys.argv) > 1:
    try:
        s = int(sys.argv[1])
    except:
        pass
if len(sys.argv) > 2:
    try:
        nMax = int(sys.argv[2])
    except:
        pass

if (nMax & 1) != 0:
    nMax += -1

if nMax > 536870912*2 and sys.maxsize == 2147483647:
    try:
        from array import array
        v = array('I',[0])*(nMax//2)
    except:
        print("Not enough memory!")
        sys.exit(0)
elif nMax >= 147026880:
    try:
        v = [0]*(nMax//2)
    except:
        try:
            from array import array
            v = array('I',[0])*(nMax//2)
        except:
            print("Not enough memory!")
            sys.exit(0)
else:
    v = bytearray(nMax//2)

nMaxSqrt = int(sqrt(nMax))

res = tatami(s)*2
if res > -1:
    print("The smallest room size s for which T(s) = "+str(s)+" is "+str(res))
else:
    print("No solution found for s=" +str(s)+" and nMax="+str(nMax))
    maxs = 0
    maxi = 0
    for i in range(0,nMax//2):
        if v[i] > maxs:
            maxs = v[i]
            maxi = i*2
    print("Maximal T(s) found = "+str(maxs)+" for room size = "+str(maxi))
It runs a bit slower in interpreter mode, but even faster with pypy3:

Code: Select all

time ./tatami_opt.py
The smallest room size s for which T(s) = 200 is 85765680

real	1m39,995s
user	1m39,781s
sys	0m0,140s

time pypy3 ./tatami_opt.py
The smallest room size s for which T(s) = 200 is 85765680

real	0m15,124s
user	0m14,871s
sys	0m0,210s
Now let us search for a solution for T(s) = 300:

Code: Select all

time pypy3 ./tatami_opt.py 300 300000000
The smallest room size s for which T(s) = 300 is 294053760

real	0m49,615s
user	0m48,143s
sys	0m1,400s
All timings are from a RPi 4B/4G
Minimal Kiosk Browser (kweb)
Slim, fast webkit browser with support for audio+video+playlists+youtube+pdf+download
Optional fullscreen kiosk mode and command interface for embedded applications
Includes omxplayerGUI, an X front end for omxplayer

ejolson
Posts: 5989
Joined: Tue Mar 18, 2014 11:47 am

Re: Liberation through Computer Literacy

Wed Nov 13, 2019 2:56 pm

gkreidl wrote:
Wed Nov 13, 2019 9:43 am
It runs a bit slower in interpreter mode, but even faster with pypy3:
Storing T(s) only for even values of s is a nice optimisation. In addition to being easier on the cache it takes less memory.

I was talking with the lead developer of FidoBasic about how to present the results of the challenge. The canine coder suggested that everyone should receive stars for any correctly working code submitted. When asked what kind of stars, the developer clicked and found
Wikipedia wrote:Sirius is known colloquially as the "Dog Star", reflecting its prominence in its constellation, Canis Major (the Greater Dog)
Then Fido became barking mad. What? growled the canine coder. That's an egregious error. Sirius is the colloquial; Dog Star is the proper scientific name.

I reflected and then remarked, I not sure we need stars. Didn't someone offer to provide free tatami mats to everyone entering the challenge? However, Fido was busy editing Wikipedia and did not respond. It's amazing how liberating it is to know how to use a computer.

User avatar
John_Spikowski
Posts: 1614
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: Liberation through Computer Literacy

Wed Nov 13, 2019 5:15 pm

The optimization takes into account, that only even room sizes are allowed. Half of the size of the v-Array is never used. 
This sounds like a precursor to threads.

Can X and Y be done In separate threads?

Tatami is rectangles not squares.

scriba tatamixy.sb 200 100


User avatar
John_Spikowski
Posts: 1614
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: Liberation through Computer Literacy

Thu Nov 14, 2019 1:08 am

My vote for the next iteration of the Tatami challenge is to pass both X and Y dimensions and not assume the room is square.

User avatar
Paeryn
Posts: 3082
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: Liberation through Computer Literacy

Thu Nov 14, 2019 1:41 am

John_Spikowski wrote:
Thu Nov 14, 2019 1:08 am
My vote for the next iteration of the Tatami challenge is to pass both X and Y dimensions and not assume the room is square.
It doesn't assume the room is square, the calculations are on the area of the room, T(s) being the number of rooms with an area of s where the width is not greater than than the height that can't be covered completely. The width <= height prevents counting duplicate identical rooms (e.g. a room of 7x10 is just a rotated copy of 10x7).
She who travels light — forgot something.
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!

User avatar
John_Spikowski
Posts: 1614
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: Liberation through Computer Literacy

Thu Nov 14, 2019 3:04 am

A slight improvement for ScriptBasic. Only the extension module code was changed.

No one has download the scriba or ta.so zips. Was that another waste of my time?

Haven't heard much from Heater. Is he still mapping the universe or him barfing on his keyboard take him offline?

Code: Select all

/* Tatami Array Get / Set / Add
UXLIBS: -lm
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../../basext.h"
#include "cbasic.h"

DIM AS unsigned char v[50000000];

/****************************
 Extension Module Functions
****************************/

besVERSION_NEGOTIATE
  RETURN_FUNCTION((int)INTERFACE_VERSION);
besEND

besSUB_START
  DIM AS long PTR p;
  besMODULEPOINTER = besALLOC(sizeof(long));
  IF (besMODULEPOINTER EQ NULL) THEN_DO RETURN_FUNCTION(0);
  p = (long PTR)besMODULEPOINTER;
  RETURN_FUNCTION(0);
besEND

besSUB_FINISH
  DIM AS long PTR p;
  p = (long PTR)besMODULEPOINTER;
  IF (p EQ NULL) THEN_DO RETURN_FUNCTION(0);
  RETURN_FUNCTION(0);
besEND


/************************
 Tatami array functions
************************/

besFUNCTION(do_v)
  DIM AS long start;
  DIM AS long end;
  DIM AS long value;
  DIM AS long idx;
  besARGUMENTS("iii")
    AT start, AT end, AT value
  besARGEND
  DEF_FOR (idx = start TO idx <= end STEP INCR idx + 2)
  BEGIN_FOR
    v[(value * idx) / 2] += 1;
  NEXT
  besRETURNVALUE = NULL;
besEND 

besFUNCTION(find_s)
  DIM AS long s;
  DIM AS long idx;
  besARGUMENTS("i")
    AT s
  besARGEND
  DEF_FOR (idx = 0 TO idx <= 49999999 STEP INCR idx)
  BEGIN_FOR
    IF (v[idx] == s) THEN
      besRETURN_LONG(idx + idx);
         EXIT_FOR
    END_IF
  NEXT
besEND  
Output (Laptop)

Code: Select all

ubuntu@ubuntu:~/sbrt/examples$ time scriba tatamix.sb 200
The smallest room size s for which T(s) = 200 is 85765680

real	0m4.859s
user	0m4.815s
sys	0m0.044s
ubuntu@ubuntu:~/sbrt/examples$ 
Output (RPI 4B 4GB)

Code: Select all

pi@RPi4B:~/sbrt/examples $ time scriba tatamix.sb 200
The smallest room size s for which T(s) = 200 is 85765680

real	0m23.399s
user	0m23.267s
sys	0m0.121s
pi@RPi4B:~/sbrt/examples $ 
Attachments
ta.so.zip
(1.9 KiB) Downloaded 33 times

User avatar
John_Spikowski
Posts: 1614
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: Liberation through Computer Literacy

Thu Nov 14, 2019 5:12 am

Tatami Python 200 (optimized)

Output (Laptop)

Code: Select all

ubuntu@ubuntu:~/sbrt/examples$ time ./tatami.py 200
The smallest room size s for which T(s) = 200 is 85765680

real	0m39.373s
user	0m39.358s
sys	0m0.012s
ubuntu@ubuntu:~/sbrt/examples$ 
Output (RPi 4B 4GB)

Code: Select all

pi@RPi4B:~/sbrt/examples $ time ./tatami.py 200
The smallest room size s for which T(s) = 200 is 85765680

real	1m45.614s
user	1m45.450s
sys	0m0.131s
pi@RPi4B:~/sbrt/examples $ 
Last edited by John_Spikowski on Thu Nov 14, 2019 5:40 am, edited 2 times in total.

User avatar
John_Spikowski
Posts: 1614
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: Liberation through Computer Literacy

Thu Nov 14, 2019 5:36 am

Tatami C (optimized)

Output (Laptop)

Code: Select all

ubuntu@ubuntu:~/sbrt/examples$ time ./tatami 200
T(85765680) = 200

real	0m3.312s
user	0m3.258s
sys	0m0.053s
ubuntu@ubuntu:~/sbrt/examples$ 
Output (RPi 4B 4GB)[/b]

Code: Select all

pi@RPi4B:~/sbrt/examples $ time ./tatami 200
T(85765680) = 200

real	0m10.417s
user	0m10.025s
sys	0m0.392s
pi@RPi4B:~/sbrt/examples $ 

Heater
Posts: 16843
Joined: Tue Jul 17, 2012 3:02 pm

Re: Liberation through Computer Literacy

Thu Nov 14, 2019 5:58 am

John_Spikowski,
Haven't heard much from Heater. Is he still mapping the universe or him barfing on his keyboard take him offline?
Still here, following along intently.

Strangely enough mapping is exactly what I have been doing. Only a small corner of the universe mind.

Was hoping to make a Rust version of one of the recent optimized C tatami codes. That might have to wait till the week end.
Memory in C++ is a leaky abstraction .

User avatar
John_Spikowski
Posts: 1614
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: Liberation through Computer Literacy

Thu Nov 14, 2019 6:18 am

Thanks for the update. A Rust version would be nice.

User avatar
John_Spikowski
Posts: 1614
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: Liberation through Computer Literacy

Thu Nov 14, 2019 6:40 am

It might be possible to run the two FOR/NEXT routines that update the V arrary as threads updating their own instance of V and returning the arrays as strings.

The final FOR/NEXT that searches for S could take the two thread array return strings as arguments and combine them before finding the S index.

Wouldn't searching backward from UBOUND towards zero be faster?

User avatar
John_Spikowski
Posts: 1614
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: Liberation through Computer Literacy

Thu Nov 14, 2019 7:06 am

Removed invalid code.
Last edited by John_Spikowski on Thu Nov 14, 2019 4:01 pm, edited 1 time in total.

User avatar
John_Spikowski
Posts: 1614
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: Liberation through Computer Literacy

Thu Nov 14, 2019 7:55 am

Show us the code!

ejolson
Posts: 5989
Joined: Tue Mar 18, 2014 11:47 am

Re: Liberation through Computer Literacy

Thu Nov 14, 2019 9:57 am

John_Spikowski wrote:
Thu Nov 14, 2019 7:06 am
Doing the reverse search shaved off a bit more time.
Searching from large values of s until T(s)=n does not necessarily find the least s that does the same. The fact that the same value for s is returned when n=200 is coincidence, so this approach does not count as working code. To further see this try solving T(s)=1 without changing smax and note that the correct answer of s=70 is not returned.

User avatar
John_Spikowski
Posts: 1614
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: Liberation through Computer Literacy

Thu Nov 14, 2019 3:55 pm

I'm going to take a shot at doing this in ScriptBasic as a string for V. It won't be as fast a the extension module version but should be able to do 200 native.

User avatar
John_Spikowski
Posts: 1614
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: Liberation through Computer Literacy

Thu Nov 14, 2019 5:24 pm

Tatami threaded
🥳

Thanks!
The pthread_join() function waits for the thread specified by thread to terminate. If that thread has already terminated, then pthread_join() returns immediately. The thread specified by thread must be joinable. If retval is not NULL, then pthread_join() copies the exit status of the target thread (i.e., the value that the target thread supplied to pthread_exit(3)) into the location pointed to by retval. If the target thread was canceled, then PTHREAD_CANCELED is placed in the location pointed to by retval. If multiple threads simultaneously try to join with the same thread, the results are undefined. If the thread calling pthread_join() is canceled, then the target thread will remain joinable (i.e., it will not be detached).

ejolson
Posts: 5989
Joined: Tue Mar 18, 2014 11:47 am

Re: Liberation through Computer Literacy

Thu Nov 14, 2019 5:41 pm

jalih wrote:
Tue Nov 12, 2019 9:30 pm
Here are updated Tatami codes for PL/1, Fortran and 8th. I use ancient PL/1 compiler for Windows but it still produces the fastest code of the bunch. PL/1 code takes about 3 seconds to run, Fortran code doubles that time and runs in about 6.5 seconds.
I suspect the Fortran code would gain performance by using a one or two-byte integer data type for the v array. A similar optimisation could be done with my Visual Basic code.

It is likely the speed of the simple but memory intensive tatami.c algorithm is constrained by memory bandwidth. This makes it more of a memory benchmark than a test of processor speed. On the other hand, limited.c may depend more on processor speed and less on memory.

As searchs for plotting packages which create stars with tatami tilings as the background are coming up short, it looks like a new programming challenge may be in the making: Write a custom plotting program. I did, however, find

Image

Could Minecraft be used to present the results of the tatami challenge?

jalih
Posts: 154
Joined: Mon Apr 15, 2019 3:54 pm

Re: Liberation through Computer Literacy

Thu Nov 14, 2019 7:16 pm

ejolson wrote:
Thu Nov 14, 2019 5:41 pm
I suspect the Fortran code would gain performance by using a one or two-byte integer data type for the v array. A similar optimisation could be done with my Visual Basic code.
Fortran integer types are signed, 8-bit and 16 bit integers are nonstandard and might not be supported by all compilers. Some compilers also accepts unsigned integer types as an extension. I tested using (kind=2) 16 bit signed integer but it did not make any difference in program run time and my ide warned about possible loss of precision.

jalih
Posts: 154
Joined: Mon Apr 15, 2019 3:54 pm

Re: Liberation through Computer Literacy

Thu Nov 14, 2019 7:51 pm

Here is a two threaded version of tatami for 8th:

Code: Select all

100000000 constant N-MAX
N-MAX n:sqrt n:int constant N-MAX-SQRT

N-MAX b:new true b:writable constant v

: swap+-  \ a b c f -- a (a+b+1) (a+c-1)
  drop
  swap 2 pick n:+ n:1+
  swap 2 pick n:+ n:1- ;

: l4  \ i k2 k3 k4 -- i k2 k3 k4
  \ i k2 k3 k4 j
  4 pick over n:*
  v over b:@ n:1+ rot swap b:! 2drop ;

: l3
  \ i
  dup 3 n:+             \ i k2=i+3
  over dup n:+ 4 n:-    \ i k2 k3=i+i-4
  repeat  \ i k2 k3
    2dup n:> not 2over n:* N-MAX n:< and if
      N-MAX n:1- 3 pick n:/ n:int     \  i k2 k3 k4
      2dup n:< if
        drop dup
      then
      ' l4 3 pick 2 pick loop   \ i k2 k3 k4
      swap+-
    else
      break
    then
  again
  2drop drop
  2 step ;

: l2  \ i k2 k3 k4 -- i k2 k3 k4
  \ i k2 k3 k4 j
  4 pick over n:*
  v over b:@ n:1+ rot swap b:! 2drop
  2 step ;

: l1
  \ i
  dup 3 n:+             \ i k2=i+3
  over dup n:+ 4 n:-    \ i k2 k3=i+i-4
  repeat  \ i k2 k3
    2dup n:> not 2over n:* N-MAX n:< and if
      N-MAX n:1- 3 pick n:/ n:int     \  i k2 k3 k4
      2dup n:< if
        drop dup
      then
      ' l2 3 pick 2 pick loop   \ i k2 k3 k4
      swap+-
    else
      break
    then
  again
  2drop drop
  2 step ;

: tatami  \ n -- s
  a:new
  ( ' l1 7 N-MAX-SQRT n:1- loop ) t:task a:push
  ( ' l3 8 N-MAX-SQRT n:1- loop ) t:task a:push
  t:wait
  v swap 1 a:close b:new b:search nip ;

: app:main
  200 tatami null? not if
    "The smallest room size s for which T(s) = 200 is %d.\n" s:strfmt .
  else
    drop "Not found\n" .
  then
  bye ;
  

User avatar
John_Spikowski
Posts: 1614
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: Liberation through Computer Literacy

Fri Nov 15, 2019 12:07 am

I use my laptop for development. My phone is used for everything else.
Last edited by John_Spikowski on Fri Nov 15, 2019 1:33 am, edited 1 time in total.

User avatar
John_Spikowski
Posts: 1614
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: Liberation through Computer Literacy

Fri Nov 15, 2019 1:21 am

Could Minecraft be used to present the results of the tatami challenge?
Farm Sim may be a better choice. It has an object IDE and BASIC like scripting engine.

User avatar
John_Spikowski
Posts: 1614
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: Liberation through Computer Literacy

Fri Nov 15, 2019 2:50 am

The V as a STRING idea didn't work out. There isn't an efficient way to replace a character within the string.

User avatar
John_Spikowski
Posts: 1614
Joined: Wed Apr 03, 2019 5:53 pm
Location: Anacortes, WA USA
Contact: Website Twitter

Re: Liberation through Computer Literacy

Fri Nov 15, 2019 3:49 am

@jcyr,

It looks like you are using one instance of the V[] array for both threads, Is there no collisions due to each thread updates separate (odd / even) elements?

Can this be done in C rather than C++?

Is it possible to do multiple areas and combined them?

Return to “General programming discussion”