Browse Source

Merge branch 'master' into done-projects

pull/455/head
Christopher Fremond 4 years ago committed by GitHub
parent
commit
007e2d8bbe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 119
      rc/README.md
  2. 754
      rc/rc.go
  3. 2
      scripts/configure_ubuntu.sh
  4. 6
      scripts/go.sh
  5. 161
      scripts/install-debian.sh
  6. 2
      subjects/abort.en.md
  7. 2
      subjects/abort.fr.md
  8. 2
      subjects/activebits.en.md
  9. 2
      subjects/activebits.fr.md
  10. 5
      subjects/addlinkednumbers.en.md
  11. 6
      subjects/addprimesum.en.md
  12. 2
      subjects/advancedsortwordarr.en.md
  13. 2
      subjects/advancedsortwordarr.fr.md
  14. 2
      subjects/alphacount.en.md
  15. 2
      subjects/alphacount.fr.md
  16. 1
      subjects/anagram.en.md
  17. 2
      subjects/any.en.md
  18. 2
      subjects/any.fr.md
  19. 2
      subjects/appendrange.en.md
  20. 2
      subjects/appendrange.fr.md
  21. 2
      subjects/ascii-art-web/ascii-art-web-export-file.audit.en.md
  22. 4
      subjects/ascii-art-web/ascii-art-web.audit.en.md
  23. 4
      subjects/atoi.en.md
  24. 2
      subjects/atoi.fr.md
  25. 2
      subjects/atoibase.en.md
  26. 2
      subjects/atoibase.fr.md
  27. 4
      subjects/atoibaseprog.en.md
  28. 2
      subjects/atoibaseprog.fr.md
  29. 4
      subjects/atoiprog.en.md
  30. 3
      subjects/balancedstring.en.md
  31. 2
      subjects/basicatoi.en.md
  32. 2
      subjects/basicatoi.fr.md
  33. 2
      subjects/basicatoi2.en.md
  34. 2
      subjects/basicatoi2.fr.md
  35. 2
      subjects/basicjoin.en.md
  36. 2
      subjects/basicjoin.fr.md
  37. 2
      subjects/btreeapplybylevel.en.md
  38. 2
      subjects/btreeapplybylevel.fr.md
  39. 2
      subjects/btreeapplyinorder.en.md
  40. 2
      subjects/btreeapplyinorder.fr.md
  41. 2
      subjects/btreeapplypostorder.en.md
  42. 2
      subjects/btreeapplypostorder.fr.md
  43. 2
      subjects/btreeapplypreorder.en.md
  44. 2
      subjects/btreeapplypreorder.fr.md
  45. 2
      subjects/btreedeletenode.en.md
  46. 2
      subjects/btreedeletenode.fr.md
  47. 2
      subjects/btreeinsertdata.en.md
  48. 2
      subjects/btreeinsertdata.fr.md
  49. 2
      subjects/btreeisbinary.en.md
  50. 2
      subjects/btreeisbinary.fr.md
  51. 2
      subjects/btreelevelcount.en.md
  52. 2
      subjects/btreelevelcount.fr.md
  53. 2
      subjects/btreemax.en.md
  54. 2
      subjects/btreemax.fr.md
  55. 2
      subjects/btreemin.en.md
  56. 2
      subjects/btreemin.fr.md
  57. 2
      subjects/btreeprintroot.en.md
  58. 2
      subjects/btreeprintroot.fr.md
  59. 2
      subjects/btreesearchitem.en.md
  60. 2
      subjects/btreesearchitem.fr.md
  61. 2
      subjects/btreetransplant.en.md
  62. 2
      subjects/btreetransplant.fr.md
  63. 2
      subjects/capitalize.en.md
  64. 2
      subjects/capitalize.fr.md
  65. 4
      subjects/changeorder.en.md
  66. 55
      subjects/chunk.en.md
  67. 2
      subjects/cl.en.md
  68. 2
      subjects/cl.fr.md
  69. 1
      subjects/cleanstr.en.md
  70. 1
      subjects/cleanstr.fr.md
  71. 2
      subjects/collatzcountdown.en.md
  72. 2
      subjects/collatzcountdown.fr.md
  73. 2
      subjects/compact.en.md
  74. 2
      subjects/compact.fr.md
  75. 2
      subjects/compare.en.md
  76. 2
      subjects/compare.fr.md
  77. 2
      subjects/compareprog.en.md
  78. 2
      subjects/concat.en.md
  79. 2
      subjects/concat.fr.md
  80. 2
      subjects/concatparams.en.md
  81. 2
      subjects/concatparams.fr.md
  82. 2
      subjects/convertbase.en.md
  83. 2
      subjects/convertbase.fr.md
  84. 24
      subjects/costumeprofit.en.md
  85. 2
      subjects/countif.en.md
  86. 2
      subjects/countif.fr.md
  87. 2
      subjects/createelem.en.md
  88. 2
      subjects/createelem.fr.md
  89. 2
      subjects/divmod.en.md
  90. 2
      subjects/divmod.fr.md
  91. 47
      subjects/doppelgangerprog.en.md
  92. 2
      subjects/enigma.en.md
  93. 2
      subjects/enigma.fr.md
  94. 60
      subjects/fib.en.md
  95. 6
      subjects/fibonacci.en.md
  96. 4
      subjects/fibonacci.fr.md
  97. 2
      subjects/findnextprime.en.md
  98. 6
      subjects/findnextprime.fr.md
  99. 53
      subjects/findprevprimeprog.en.md
  100. 2
      subjects/firstrune.en.md
  101. Some files were not shown because too many files changed in this diff diff.show_more

119
rc/README.md

@ -0,0 +1,119 @@
## rc (restrictions checker)
This program analyses a go source file and displays in standard output the imports, functions, array types and loops used without authorization.
### By default:
- NO imports and NO built-in functions are allowed.
- NO casting is allowed either.
- Only functions declared inside the source file are allowed.
- All array types are allowed
- Loops are allowed
### Flags
- Two flags are defined:
- `--cast` allows casting to every built-in type.
- `--no-for` prohibits the use of `for` loops in the program or function.
- `--no-array`:
- Prohibits all array types if no types are specified after the flag.
Ex.
```console
_$ ./rc main.go fmt.* github.com/01-edu/z01.PrintRune len --no-array
```
All array type in main.go will cause an error message.
- Prohibits only the types specified after the flag
Ex.
```console
_$ ./rc main.go fmt.* github.com/01-edu/z01.PrintRune len --no-array rune string
```
Only array from the type rune and string are prohibit. All other array from built-in types are allowed
### Arguments:
- First Argument:
The program must be executed passing the go source file to be analyze as the first argument
- The remaining argument (from 2 to ...):
Can be (without any particular order):
- Allowed imports and functions from a package
- `<package>.*` for full imports (all functions from that package are allowed)
- `<package>`.`<function>` for partial imports (only the function is allowed)
- `<package>`.`<function>#amout` for certain amounts (only certain amount os a function is allowed)
- Ex: `fmt.*` (all functions from `fmt` are allowed), `github.com/01-edu/z01.PrintRune` (only `z01.PrintRune` is allowed), `append#2` (the only amount of `append`'s allowed is 2)
- Allowed built-in functions
- Use the name of the built-in function
- Ex: `make`, `append`, `len`.
- Allowed casting
- by using the type of casting, ex: for allowing `string` casting, use `string`
- Or use the flag `--cast`, to allow every type of casting
- Import relative packages
- Use the relative path
- Ex: `../piscine`, `..`, `.`
- Unallow for loops
- Use the flags `--no-for`.
- Note: remember to use it before the `--no-array` flag.
- ex:
```console
_$ ./rc main.go fmt.* github.com/01-edu/z01.PrintRune len --no-array <...> --no-for
```
the last line produces undesired behaviors.
- Unallow literals
- Use the flag `--no-lit="{PATTERN}"`
- Note: `"{PATTERN}"` must be a valid RegExp.
- ex:
```console
_$ ./rc main.go fmt.* github.com/01-edu/z01.PrintRune len --no-array --no-lit=[b-yB-Y]
```
- Optional lasts arguments
- The flag `--no-array` must be given as the last argument or to signal that all the arguments after are unallowed array types
### Usage:
- To allow the import of the whole `fmt` package, `z01.PrintRune` and the built-in functions len in the file `main.go`
The imports must be writen exactly the way are writen inside the source code, example:
```console
_$ ./rc main.go fmt.* github.com/01-edu/z01.PrintRune len
```
- More examples:
- import "fmt" is allowed by executing
```console
_$ ./rc sourcefile.go fmt.*
```
- import "go/parser" is allowed by executing
```console
_$ ./rc sourcefile.go go/parser.*
```
- import "github.com/01-edu/z01" is allowed by executing
```console
./rc sourcefile.go github.com/01-edu/z01.*
```
- import "../../../all/tests/go/solutions" is allowed by executing
```console
_$ ./rc sourcefile.go ../../../all/tests/go/solutions
```
(no `.*` is needed, all the functions from this relative package are allowed)
- allow all type of casting
```console
_$ ./rc sourcefile.go ../../../all/tests/go/solutions/ztail/ztail.go fmt.* github.com/01-edu/z01 os.* strconv.* make len append --cast
```
- this will allow all type of casting in the file ztail.go
- to allow just one type of casting
```console
_$ ./rc sourcefile.go ../../../all/tests/go/solutions/ztail/ztail.go fmt.* github.com/01-edu/z01 os.* strconv.* make len append rune
```
- this will allow `rune`, but not `int8`, ..., `string`, `float32`, ...

754
rc/rc.go

@ -0,0 +1,754 @@
package main
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
"log"
"os"
"regexp"
"strconv"
"strings"
)
const (
identation = " "
)
var (
allowedImp map[string]map[string]bool // Map of the allowed imports
allowedFun map[string]bool // Map of the allowed built-in functions
// Is necessary an array to keep all the call instances.
callX []nodePos // Keeps the name of the called functions and the position in the file.
// A map is enough for function declarations because they are unique.
funcDeclPkg map[string]*funcBody // Keeps the name of the function associated to its body and its position in the file.
allArrayTypes = true
arraysInstances []nodePos
forStmts []nodePos
basicLits []nodePos
illegals []illegal
notAllowedArrayT []string
predeclaredTypes = []string{"bool", "byte", "complex64", "complex128",
"error", "float32", "float64", "int", "int8",
"int16", "int32", "int64", "rune", "string",
"uint", "uint8", "uint16", "uint32", "uint64",
"uintptr",
}
relativeImports []string
importPkg map[string]*pkgFunc
pkgName []string
allImports map[string]bool
openImports []string
funcOccurrences map[string]int
)
//pkgFunc for all the functions of a given package
type pkgFunc struct {
functions []string
path string
}
type funcImp struct {
pkg, fun string
pos token.Pos
}
// All visitors
type callVisitor struct {
Calls []string
Fset *token.FileSet
}
type fileVisitor struct {
funcDecl []string
funcCalls []string
selectExpr []string
arrayType []nodePos
Fset *token.FileSet
}
type pkgVisitor struct {
Fset *token.FileSet
}
type impVisitor struct {
Fset *token.FileSet
relativeImports []string
}
// Get the position of the node in the file
type locate interface {
getPos(ast.Node) string
}
func (i *impVisitor) getPos(n ast.Node) string {
return i.Fset.Position(n.Pos()).String()
}
func (fv *fileVisitor) getPos(n ast.Node) string {
return fv.Fset.Position(n.Pos()).String()
}
func (p *pkgVisitor) getPos(n ast.Node) string {
return p.Fset.Position(n.Pos()).String()
}
func (c *callVisitor) getPos(n ast.Node) string {
return c.Fset.Position(n.Pos()).String()
}
type illegal struct {
T string
Name string
Pos string
}
func (i *illegal) String() string {
return i.T + " " + i.Name + " " + i.Pos
}
func getPkgFunc(path string, fsetPkg *token.FileSet) {
i := &impVisitor{Fset: fsetPkg}
p := &pkgVisitor{Fset: fsetPkg}
pkgs, err := parser.ParseDir(fsetPkg, path, nil, parser.AllErrors)
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
for pkgname := range pkgs {
pkg, _ := ast.NewPackage(fsetPkg, pkgs[pkgname].Files, nil, nil)
pkgName = append(pkgName, pkgname)
ast.Walk(i, pkg)
ast.Walk(p, pkg)
for _, v := range i.relativeImports {
if isIn(v, openImports) {
break
}
openImports = append(openImports, v)
getPkgFunc(path+"/"+v, fsetPkg)
}
}
}
//reformat from the data base
func splitArgs(args string) []string {
result := strings.Split(args, " ")
return result
}
func rightFile(args string) string {
expectedFiles := splitArgs(args)
for _, s := range expectedFiles {
if strings.Contains(s, ".go") {
return s
}
}
return ""
}
func allowCastingAndImp(allowedImports []string) {
casted := false
for i, v := range allowedImports {
casted = allow(v, casted)
if v == "--no-array" {
allArrayTypes = false
notAllowedArrayT = append(notAllowedArrayT, allowedImports[i+1:]...)
break
}
}
}
type flags struct {
l struct { // flag for char or string literal
noLit bool // true -> unallows
pattern string // this pattern
}
}
// TODO: treat all the flags in this function
// For now, only --no-lit="{PATTERN}"
func parseFlags(args []string) *flags {
f := &flags{}
for _, v := range args {
var flag []string
if strings.Contains(v, "=") {
flag = strings.Split(v, "=")
}
if flag == nil {
continue
}
if flag[0] == "--no-lit" {
f.l.noLit = true
f.l.pattern = flag[1]
}
}
return f
}
func removeAmount(s string) string {
strRm := strings.TrimFunc(s, func(c rune) bool {
return c >= '0' && c <= '9' || c == '#'
})
return strRm
}
//compares if the function is used a certain amount of times allowed
func allowedAmount(occurrences map[string]int, allowedImports []string) {
function := ""
funcSelector := ""
for _, v := range allowedImports {
//pkg in case it's a build in function and slice in case it's a selector function
pkg, slice := trimRelativeImport(v)
if slice != nil {
function = strings.Join(slice, ".")
funcSelector = removeAmount(function)
} else {
function = pkg
funcSelector = removeAmount(pkg)
}
if strings.ContainsAny(function, "#") {
strNbr := strings.TrimPrefix(function, funcSelector+"#")
nbr, err := strconv.Atoi(strNbr)
if err != nil {
log.Panic(err)
}
if occurrences[funcSelector] > nbr {
illegals = append(illegals, illegal{
T: "illegal-amount",
Name: funcSelector + " allowed count " + strNbr + " your count " + strconv.Itoa(occurrences[funcSelector]),
})
}
}
}
}
func main() {
if len(os.Args) < 2 {
fmt.Println("No file or directory")
return
}
var allowedImports []string
if len(os.Args) > 2 {
allowedImports = splitArgs(os.Args[2])
}
allowCastingAndImp(allowedImports)
flag := parseFlags(allowedImports)
filename := strings.TrimSpace(rightFile(os.Args[1]))
split := strings.Split(filename, "/")
path := strings.Join(split[:len(split)-1], "/")
if path == "" {
path = "."
}
fsetFile := token.NewFileSet()
fsetPkg := token.NewFileSet()
fmt.Println("Parsing")
file, err := parser.ParseFile(fsetFile, filename, nil, parser.AllErrors)
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
// Get all the name of all functions declared in the file
w := &fileVisitor{Fset: fsetFile}
ast.Walk(w, file)
getPkgFunc(path, fsetPkg)
for _, v := range w.funcDecl {
isFuncAllowed(v, fsetPkg)
}
// TODO: Parsing the arguments for the --max-occurrences flag
allowedAmount(funcOccurrences, allowedImports)
if flag != nil {
flag.unallowLits()
}
analyzeArrayT()
analyzeForStmt(allowedImports)
fmt.Println(identation + "OK")
fmt.Println("Cheating")
if len(illegals) > 0 {
for _, i := range illegals {
fmt.Println(identation + i.String())
}
os.Exit(1)
} else {
fmt.Println(identation + "OK")
}
}
func (f flags) unallowLits() {
if f.l.noLit {
for _, v := range basicLits {
if !f.isLitAllowed(v.name) {
illegals = append(illegals, illegal{
T: "illegal-literal",
Name: v.name,
Pos: v.position,
})
}
}
}
}
func (f flags) isLitAllowed(s string) bool {
matched, err := regexp.Match(f.l.pattern, []byte(s))
if err != nil {
return true
}
return !matched
}
func analyzeForStmt(args []string) {
if isIn("--no-for", args) {
for _, v := range forStmts {
illegals = append(illegals, illegal{
T: "illegal-loop",
Name: v.name,
Pos: v.position,
})
}
}
}
func analyzeArrayT() {
if !allArrayTypes {
l := len(notAllowedArrayT)
for _, v := range arraysInstances {
if l == 0 ||
isIn(v.name, notAllowedArrayT) {
illegals = append(illegals, illegal{
T: "illegal-array-type",
Name: v.name,
Pos: v.position,
})
}
}
}
}
func allow(s string, casted bool) bool {
if strings.ContainsRune(s, '.') {
allowImport(s)
} else {
if allowedFun == nil {
allowedFun = make(map[string]bool)
}
if strings.ContainsAny(s, "#") {
s = removeAmount(s)
}
allowedFun[s] = true
}
if s == "--cast" && !casted {
for _, v := range predeclaredTypes {
allow(v, false)
}
return true
}
return casted
}
// Returns true if the string matches the format of a relative import
func isRelativeImport(s string) bool {
relativeImport, _ := regexp.MatchString(`\.\.\\??`, s)
return relativeImport
}
// Returns true if the string represents an import package
// i.e and expresion like <lib>.<function>
func isImport(s string) bool {
matched, _ := regexp.MatchString(`.\..`, s)
return matched
}
func trimRelativeImport(str string) (string, []string) {
var pkg string
var slice []string
if isImport(str) && !isRelativeImport(str) {
splited := strings.Split(str, "/")
slice = strings.Split(splited[len(splited)-1], ".")
splited[len(splited)-1] = slice[0]
pkg = strings.Join(splited, "/")
if allowedImp[slice[0]] == nil {
allowedImp[slice[0]] = make(map[string]bool)
}
fn := slice[len(slice)-1]
allowedImp[slice[0]][fn] = true
} else {
pkg = str
}
return pkg, slice
}
func allowImport(s string) {
if allowedImp == nil {
allowedImp = make(map[string]map[string]bool)
}
if allImports == nil {
allImports = make(map[string]bool)
}
pkg, slice := trimRelativeImport(s)
allImports[pkg] = true
fn := "*"
if len(slice) > 1 {
fn = removeAmount(slice[1])
}
if allowedImp[pkg] == nil {
allowedImp[pkg] = make(map[string]bool)
}
allowedImp[pkg][fn] = true
}
func addToIllegals(funcname string) {
for _, v := range callX {
if v.name == funcname {
pos := v.position
setIllegal("illegal-call", v.name, pos)
}
}
if funcDeclPkg[funcname] != nil {
pos := funcDeclPkg[funcname].position
setIllegal("illegal-call", funcname, pos)
}
}
// First ignoring the imported functions
func isFuncAllowed(funcname string, fset *token.FileSet) bool {
if allowedFun[funcname] {
return true
}
if !isFuncDeclIn(funcname, funcDeclPkg) {
addToIllegals(funcname)
return false
}
bodyf := funcDeclPkg[funcname].body
if bodyf == nil {
addToIllegals(funcname)
fmt.Println("Body is nil")
return false
}
c := &callVisitor{Fset: fset}
ast.Walk(c, bodyf)
res := true
for _, v := range c.Calls {
if v == funcname {
continue
}
allowed := isFuncAllowed(v, fset)
if !allowed {
addToIllegals(funcname)
for _, v := range c.Calls {
if v == funcname {
continue
}
allowed := isFuncAllowed(v, fset)
if !allowed {
addToIllegals(funcname)
}
res = res && allowed
}
}
res = res && allowed
}
return res
}
func isFuncDeclIn(funcname string, fundecl map[string]*funcBody) bool {
return fundecl[funcname] != nil
}
func isFuncCallIn(funcname string, funP []nodePos) bool {
for _, v := range funP {
if v.name == funcname {
return true
}
}
return false
}
func isIn(s string, slc []string) bool {
for _, v := range slc {
if s == v {
return true
}
}
return false
}
// Keeps the positions of each function call and declaration
type funcBody struct {
position string
body *ast.BlockStmt
}
type nodePos struct {
position string
name string
}
func (fv *fileVisitor) Visit(n ast.Node) ast.Visitor {
fv.checkImport(n)
if ide, ok := n.(*ast.CallExpr); ok {
if opt, ok := ide.Fun.(*ast.Ident); ok {
fv.funcCalls = append(fv.funcCalls, opt.Name)
newFun := nodePos{position: fv.getPos(n), name: opt.Name}
callX = append(callX, newFun)
}
}
if expr, ok := n.(*ast.SelectorExpr); ok {
if x, ok := expr.X.(*ast.Ident); ok {
fv.selectExpr = append(fv.selectExpr, x.Name+"."+expr.Sel.Name)
//saves the function in to the map, from the package
if importPkg[x.Name] != nil {
importPkg[x.Name].functions = append(importPkg[x.Name].functions, x.Name+"."+expr.Sel.Name)
}
if funcOccurrences == nil {
funcOccurrences = make(map[string]int)
}
funcOccurrences[x.Name+"."+expr.Sel.Name]++
}
}
if ex, ok := n.(*ast.ArrayType); ok {
if op, ok := ex.Elt.(*ast.Ident); ok {
fv.arrayType = append(fv.arrayType, nodePos{
name: op.Name,
position: fv.getPos(n),
})
}
}
if exp, ok := n.(*ast.FuncDecl); ok {
fv.funcDecl = append(fv.funcDecl, exp.Name.Name)
for _, v := range exp.Type.Params.List {
if _, ok := v.Type.(*ast.FuncType); ok {
if allowedFun == nil {
allowedFun = make(map[string]bool)
}
for _, name := range v.Names {
allowedFun[name.Name] = true
}
}
}
}
if ex, ok := n.(*ast.AssignStmt); ok {
if exp, ok := ex.Rhs[0].(*ast.FuncLit); ok {
if ide, ok := ex.Lhs[0].(*ast.Ident); ok {
if funcDeclPkg == nil {
funcDeclPkg = make(map[string]*funcBody)
}
funcDeclPkg[ide.Name] = &funcBody{body: exp.Body, position: fv.getPos(n)}
}
}
}
return fv
}
func positionIsIn(illegals []illegal, pos string) bool {
for _, v := range illegals {
if v.Pos == pos {
return true
}
}
return false
}
func (p *pkgVisitor) Visit(n ast.Node) ast.Visitor {
if exp, ok := n.(*ast.FuncDecl); ok {
if funcDeclPkg == nil {
funcDeclPkg = make(map[string]*funcBody)
}
funcDeclPkg[exp.Name.Name] = &funcBody{body: exp.Body, position: p.getPos(n)}
for _, pkg := range pkgName {
if importPkg[pkg] != nil && isIn(pkg+"."+exp.Name.Name, importPkg[pkg].functions) {
funcDeclPkg[pkg+"."+exp.Name.Name] = &funcBody{body: exp.Body, position: p.getPos(n)}
}
}
}
if ex, ok := n.(*ast.AssignStmt); ok {
if exp, ok := ex.Rhs[0].(*ast.FuncLit); ok {
if ide, ok := ex.Lhs[0].(*ast.Ident); ok {
if funcDeclPkg == nil {
funcDeclPkg = make(map[string]*funcBody)
}
funcDeclPkg[ide.Name] = &funcBody{body: exp.Body, position: p.getPos(n)}
}
}
}
return p
}
func setIllegal(illegalType, funcName, pos string) {
if !positionIsIn(illegals, pos) {
illegals = append(illegals, illegal{
T: illegalType,
Name: funcName,
Pos: pos,
})
}
}
// Signals that exists at least one callExpr in the node
func (c *callVisitor) Visit(n ast.Node) ast.Visitor {
if id, ok := n.(*ast.BasicLit); ok {
if id.Kind != token.CHAR && id.Kind != token.STRING {
return nil
}
basicLits = append(basicLits, nodePos{position: c.getPos(n), name: id.Value})
}
if exp, ok := n.(*ast.CallExpr); ok {
if fun, ok := exp.Fun.(*ast.Ident); ok {
c.Calls = append(c.Calls, fun.Name)
newFun := nodePos{position: c.getPos(n), name: fun.Name}
callX = append(callX, newFun)
if funcOccurrences == nil {
funcOccurrences = make(map[string]int)
}
funcOccurrences[fun.Name]++
return c
}
}
// SelectorExpr is when we access a value (dot opperator)
// We need to check those for specific functions
if expr, ok := n.(*ast.SelectorExpr); ok {
x, ok := expr.X.(*ast.Ident)
if !ok {
// in this case we are deep in an access
// example, fmt is banned, but pouet isn't.
// we must allow pouet.fmt.x but not fmt.x
// this is the pouet.fmt.x case.
return c
}
pkg := allowedImp[x.Name]
f := x.Name + "." + expr.Sel.Name
if funcDeclPkg[f] != nil {
c.Calls = append(c.Calls, f)
return c
}
if pkg == nil {
if allImports[x.Name] {
pos := c.getPos(n)
setIllegal("illegal-access", f, pos)
}
return c
}
if !pkg["*"] && !pkg[expr.Sel.Name] {
// all the package is not whiteList and is not explicitly allowed
pos := c.getPos(n)
setIllegal("illegal-access", f, pos)
}
}
if ex, ok := n.(*ast.ArrayType); ok {
if op, ok := ex.Elt.(*ast.Ident); ok {
arraysInstances = append(arraysInstances, nodePos{
name: op.Name,
position: c.getPos(n),
})
}
}
if _, ok := n.(*ast.ForStmt); ok {
forStmts = append(forStmts, nodePos{
name: "for",
position: c.getPos(n),
})
}
return c
}
func (fv *fileVisitor) checkImport(n ast.Node) ast.Visitor {
if spec, ok := n.(*ast.ImportSpec); ok {
pkg := spec.Path.Value[1 : len(spec.Path.Value)-1]
if allowedImp[pkg] == nil {
pos := fv.getPos(n)
setIllegal("illegal-import", pkg, pos)
return fv
}
// if the import is named, we need to move it to the new name
name := ""
if spec.Name != nil {
name = spec.Name.Name
} else if strings.ContainsRune(pkg, '/') {
parts := strings.Split(pkg, "/")
name = parts[len(parts)-1]
}
if allowedImp[pkg] != nil {
if name != "" {
allowedImp[name] = allowedImp[pkg]
allowedImp[pkg] = nil
}
}
if isRelativeImport(pkg) {
if importPkg == nil {
importPkg = make(map[string]*pkgFunc)
}
if name != "" {
importPkg[name] = &pkgFunc{
path: pkg,
}
}
relativeImports = append(relativeImports, name)
}
}
return fv
}
func (i *impVisitor) Visit(n ast.Node) ast.Visitor {
if spec, ok := n.(*ast.ImportSpec); ok {
pkg := spec.Path.Value[1 : len(spec.Path.Value)-1]
if allImports == nil {
allImports = make(map[string]bool)
}
pkgSplit := strings.Split(pkg, "/")
allImports[pkg] = true
allImports[pkgSplit[len(pkgSplit)-1]] = true
if isRelativeImport(pkg) {
i.relativeImports = append(i.relativeImports, pkg)
}
}
return i
}

2
scripts/configure_ubuntu.sh

@ -154,7 +154,7 @@ rm -f /swapfile
sed -i '/swapfile/d' /etc/fstab
# Put temporary and cache folders as tmpfs
echo 'tmpfs /tmp tmpfs defaults,noatime,rw,nosuid,nodev,noexec,mode=1777,size=1G 0 0' >> /etc/fstab
echo 'tmpfs /tmp tmpfs defaults,noatime,rw,nosuid,nodev,mode=1777,size=1G 0 0' >> /etc/fstab
# Install additional drivers
ubuntu-drivers install ||:

6
scripts/go.sh

@ -6,9 +6,9 @@ script_dir="$(cd -P "$(dirname "$BASH_SOURCE")" && pwd)"
cd $script_dir
. set.sh
wget https://dl.google.com/go/go1.13.7.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.13.7.linux-amd64.tar.gz
rm go1.13.7.linux-amd64.tar.gz
wget https://dl.google.com/go/go1.14.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.14.linux-amd64.tar.gz
rm go1.14.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> /etc/profile
# Set-up all users

161
scripts/install-debian.sh

@ -0,0 +1,161 @@
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
set -euo pipefail
IFS='
'
# Debian stable OS
apt-get update
apt-get -y upgrade
apt-get -y dist-upgrade
# Disable OpenStack SSH malware
mv /home/debian/.ssh/authorized_keys /root/.ssh/authorized_keys ||:
sed -i '/Generated-by-Nova/d' /root/.ssh/authorized_keys ||:
chown root:root /root/.ssh/authorized_keys ||:
# Terminal goodies
touch .hushlogin
cat <<'EOF'>> /root/.bashrc
export LS_OPTIONS="--color=auto"
eval "`dircolors`"
alias ctop="docker run --rm -it --name=ctop -v /var/run/docker.sock:/var/run/docker.sock:ro quay.io/vektorlab/ctop"
alias df="df --si"
alias du="du -cs --si"
alias free="free -h --si"
alias l="ls $LS_OPTIONS -al --si --group-directories-first"
alias less="less -i"
alias nano="nano -clDOST4"
alias pstree="pstree -palU"
alias gobuild='CGO_ENABLED=0 GOARCH=amd64 go build -trimpath -ldflags="-s -w"'
export HISTFILESIZE=
export HISTSIZE=
export HISTTIMEFORMAT="%F %T "
GOPATH=$HOME/go
HISTCONTROL=ignoreboth
HISTFILESIZE=
HISTSIZE=
HISTTIMEFORMAT="%F %T "
EOF
cat <<EOF>> /etc/inputrc
set completion-ignore-case
set show-all-if-ambiguous On
set show-all-if-unmodified On
EOF
cat <<EOF>> /etc/bash.bashrc
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
EOF
# Basic packages
apt-get -y install man bash-completion git ufw jq curl build-essential netcat wget psmisc lz4 file net-tools brotli unzip zip moreutils xauth sysfsutils rsync iperf pv tree mc screen
# Configure screen
cat <<'EOF'>> /etc/screenrc
startup_message off
shell -$SHELL
defscrollback 100000
bind l eval clear "scrollback 0" "scrollback 100000"
EOF
# Configure SSH
cat <<EOF>> /etc/ssh/sshd_config
Port 521
PasswordAuthentication no
AllowUsers root
X11UseLocalhost no
EOF
service ssh restart
touch /root/.Xauthority
# Firewall
ufw allow in 80/tcp
ufw allow in 443/tcp
ufw allow in 521/tcp
ufw logging off
ufw --force enable
ufw --force delete 4
ufw --force delete 4
ufw --force delete 4
# Optimize
systemctl disable unattended-upgrades.service apt-daily.timer apt-daily-upgrade.timer console-setup.service keyboard-setup.service remote-fs.target man-db.timer systemd-timesyncd.service
apt-get -y purge apparmor
sed -i 's/MODULES=most/MODULES=dep/g' /etc/initramfs-tools/initramfs.conf
sed -i 's/COMPRESS=gzip/COMPRESS=lz4/g' /etc/initramfs-tools/initramfs.conf
update-initramfs -u
echo 'GRUB_TIMEOUT=0' >> /etc/default/grub
update-grub
apt-get -y purge exim\*
for i in $(seq 0 $(nproc --ignore 1)); do
echo "devices/system/cpu/cpu${i}/cpufreq/scaling_governor = performance" >> /etc/sysfs.conf
done
# Disable sleep when closing laptop screen
echo HandleLidSwitch=ignore >> /etc/systemd/logind.conf
# noatime
sed -i 's| / ext4 | / ext4 noatime,|g' /etc/fstab
# Disable swap
swapoff -a
sed -i '/swap/d' /etc/fstab
# node.JS & yarn
curl -sL https://deb.nodesource.com/setup_12.x | bash -
apt-get -y install nodejs
curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list
apt-get update
apt-get -y install yarn
# Docker
apt-get -y install apt-transport-https ca-certificates curl gnupg2 software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
apt-get update
apt-get -y install docker-ce docker-ce-cli containerd.io
# ripgrep
curl -LO https://github.com/BurntSushi/ripgrep/releases/download/11.0.2/ripgrep_11.0.2_amd64.deb
dpkg -i ripgrep_11.0.2_amd64.deb
rm ripgrep_11.0.2_amd64.deb
# Go
wget https://dl.google.com/go/go1.14.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.14.linux-amd64.tar.gz
rm go1.14.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> /etc/profile
# Netdata
# bash <(curl -Ss https://my-netdata.io/kickstart-static64.sh) --no-updates --stable-channel --disable-telemetry
# Caddy
curl https://getcaddy.com | bash -s personal http.ipfilter
# Generate SSH key
ssh-keygen -ted25519 -f ~/.ssh/id_ed25519 -N ''
# Cleanup
sed -i '/^deb-src/d' /etc/apt/sources.list
apt-get update
apt-get -y purge unattended-upgrades
apt-get -y autoremove --purge
apt-get clean
# The end
reboot

2
subjects/abort.en.md

@ -14,7 +14,7 @@ func Abort(a, b, c, d, e int) int {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/abort.fr.md

@ -14,7 +14,7 @@ func Abort(a, b, c, d, e int) int {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/activebits.en.md

@ -14,7 +14,7 @@ func ActiveBits(n int) uint {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/activebits.fr.md

@ -14,7 +14,7 @@ func ActiveBits(n int) uint {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

5
subjects/addlinkednumbers.en.md

@ -27,7 +27,7 @@ type NodeAddL struct {
Num int
}
func AddLinkedNumbers(num1, num1 *NodeAddL) *NodeAddL {
func AddLinkedNumbers(num1, num2 *NodeAddL) *NodeAddL {
}
```
@ -44,8 +44,7 @@ import (
)
func pushFront(node *NodeAddL, num int) *NodeAddL {
// ...
// Write yourself
}
func main() {

6
subjects/addprimesum.en.md

@ -14,6 +14,12 @@ student@ubuntu:~/[[ROOT]]/test$ ./test 5
10
student@ubuntu:~/[[ROOT]]/test$ ./test 7
17
student@ubuntu:~/[[ROOT]]/test$ ./test -2
0
student@ubuntu:~/[[ROOT]]/test$ ./test 0
0
student@ubuntu:~/[[ROOT]]/test$ ./test
0
student@ubuntu:~/[[ROOT]]/test$ ./test 5 7
0
student@ubuntu:~/[[ROOT]]/test$

2
subjects/advancedsortwordarr.en.md

@ -14,7 +14,7 @@ func AdvancedSortWordArr(array []string, f func(a, b string) int) {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/advancedsortwordarr.fr.md

@ -14,7 +14,7 @@ func AdvancedSortWordArr(array []string, f func(a, b string) int) {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/alphacount.en.md

@ -17,7 +17,7 @@ func AlphaCount(str string) int {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/alphacount.fr.md

@ -17,7 +17,7 @@ func AlphaCount(str string) int {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

1
subjects/anagram.en.md

@ -34,6 +34,7 @@ Here is a possible program to test your function:
```go
package main
import (
piscine ".."
"fmt"

2
subjects/any.en.md

@ -16,7 +16,7 @@ func Any(f func(string) bool, arr []string) bool {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/any.fr.md

@ -16,7 +16,7 @@ func Any(f func(string) bool, arr []string) bool {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/appendrange.en.md

@ -20,7 +20,7 @@ func AppendRange(min, max int) []int {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/appendrange.fr.md

@ -20,7 +20,7 @@ func AppendRange(min, max int) []int {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/ascii-art-web/ascii-art-web-export-file.audit.en.md

@ -6,7 +6,7 @@
###### Does the exported file matches the output?
##### Try to open and change the exported file.
###### Are the exported files read and write for the user only?
###### Are the exported files read and write for the user?
###### Does the project use the HTTP header [Content-Type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) to indicate the media type of the resource?

4
subjects/ascii-art-web/ascii-art-web.audit.en.md

@ -73,8 +73,8 @@ o-o-o o--o o-o o o o o-o | | o o
##### Try to navigate between all the available pages in the website.
###### Are all the pages working? Does the project implement [404 status](https://www.restapitutorial.com/httpstatuscodes.html)?
###### Does the project implement HTTP status [400 bad request](https://kinsta.com/knowledgebase/400-bad-request/#causes)?
###### Does the project implement HTTP status [500 internal server error](https://www.restapitutorial.com/httpstatuscodes.html)?
###### Does the project handle [HTTP status 400 - Bad Request](https://kinsta.com/knowledgebase/400-bad-request/#causes)?
###### Does the project handle [HTTP status 500 - Internal Server Errors](https://www.restapitutorial.com/httpstatuscodes.html)?
##### Try making a request to the server (clicking a button to generate the ascii-art representation on the website)
###### Is the communication between [server and client](https://www.geeksforgeeks.org/client-server-model/) well established?

4
subjects/atoi.en.md

@ -2,7 +2,7 @@
### Instructions
- Write a [function](TODO-LINK) that simulates the behaviour of the `Atoi` function in Go. `Atoi` transforms a number represented as a `string` in a number represented as an `int`.
- Write a function that simulates the behaviour of the `Atoi` function in Go. `Atoi` transforms a number represented as a `string` in a number represented as an `int`.
- `Atoi` returns `0` if the `string` is not considered as a valid number. For this exercise **non-valid `string` chains will be tested**. Some will contain non-digits characters.
@ -20,7 +20,7 @@ func Atoi(s string) int {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/atoi.fr.md

@ -20,7 +20,7 @@ func Atoi(s string) int {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/atoibase.en.md

@ -28,7 +28,7 @@ func AtoiBase(s string, base string) int {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/atoibase.fr.md

@ -26,7 +26,7 @@ func AtoiBase(s string, base string) int {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

4
subjects/atoibaseprog.en.md

@ -15,7 +15,7 @@ This means that:
Write a function that takes a `string` number and its `string` base in parameters and returns its conversion as an `int`.
If the base or the `string` number is not valid it returns `0`:
If the base or the `string` number is not valid it returns `0`
Validity rules for a base :
@ -37,7 +37,7 @@ func AtoiBase(s string, base string) int {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/atoibaseprog.fr.md

@ -37,7 +37,7 @@ func AtoiBase(s string, base string) int {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

4
subjects/atoiprog.en.md

@ -13,7 +13,7 @@ This means that:
### Instructions
- Write a [function](TODO-LINK) that simulates the behaviour of the `Atoi` function in Go. `Atoi` transforms a number represented as a `string` in a number represented as an `int`.
- Write a function that simulates the behaviour of the `Atoi` function in Go. `Atoi` transforms a number represented as a `string` in a number represented as an `int`.
- `Atoi` returns `0` if the `string` is not considered as a valid number. For this exercise **non-valid `string` chains will be tested**. Some will contain non-digits characters.
@ -31,7 +31,7 @@ func Atoi(s string) int {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

3
subjects/balancedstring.en.md

@ -4,7 +4,8 @@
Balanced string is a string that has equal quantity of 'C' and 'D' characters.
Write a program that takes a string and outputs maximum amount of balanced strings with `\n` at the end of line.
Write a program that takes a string and outputs maximum amount of balanced strings without ignoring any letters.
Display output with `\n` at the end of line.
If the number of arguments is not 1, display `\n`.

2
subjects/basicatoi.en.md

@ -20,7 +20,7 @@ func BasicAtoi(s string) int {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/basicatoi.fr.md

@ -20,7 +20,7 @@ func BasicAtoi(s string) int {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/basicatoi2.en.md

@ -20,7 +20,7 @@ func BasicAtoi2(s string) int {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/basicatoi2.fr.md

@ -20,7 +20,7 @@ func BasicAtoi2(s string) int {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/basicjoin.en.md

@ -14,7 +14,7 @@ func BasicJoin(strs []string) string {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/basicjoin.fr.md

@ -14,7 +14,7 @@ func BasicJoin(strs []string) string {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/btreeapplybylevel.en.md

@ -14,7 +14,7 @@ func BTreeApplyByLevel(root *TreeNode, f func(...interface{}) (int, error)) {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/btreeapplybylevel.fr.md

@ -14,7 +14,7 @@ func BTreeApplyByLevel(root *TreeNode, fn interface{}) {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/btreeapplyinorder.en.md

@ -14,7 +14,7 @@ func BTreeApplyInorder(root *TreeNode, f func(...interface{}) (int, error)) {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/btreeapplyinorder.fr.md

@ -14,7 +14,7 @@ func BTreeApplyInorder(root *TreeNode, f func(...interface{}) (int, error)) {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/btreeapplypostorder.en.md

@ -14,7 +14,7 @@ func BTreeApplyPostorder(root *TreeNode, f func(...interface{}) (int, error)) {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/btreeapplypostorder.fr.md

@ -14,7 +14,7 @@ func BTreeApplyPostorder(root *piscine.TreeNode, f func(...interface{}) (int, er
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/btreeapplypreorder.en.md

@ -14,7 +14,7 @@ func BTreeApplyPreorder(root *TreeNode, f func(...interface{}) (int, error)) {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/btreeapplypreorder.fr.md

@ -14,7 +14,7 @@ func BTreeApplyPreorder(root *TreeNode, f func(...interface{}) (int, error)) {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/btreedeletenode.en.md

@ -16,7 +16,7 @@ func BTreeDeleteNode(root, node *TreeNode) *TreeNode {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/btreedeletenode.fr.md

@ -16,7 +16,7 @@ func BTreeDeleteNode(root, node *TreeNode) *TreeNode {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/btreeinsertdata.en.md

@ -21,7 +21,7 @@ func BTreeInsertData(root *TreeNode, data string) *TreeNode {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/btreeinsertdata.fr.md

@ -21,7 +21,7 @@ func BTreeInsertData(root *TreeNode, data string) *TreeNode {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/btreeisbinary.en.md

@ -14,7 +14,7 @@ func BTreeIsBinary(root *TreeNode) bool {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/btreeisbinary.fr.md

@ -14,7 +14,7 @@ func BTreeIsBinary(root *TreeNode) bool {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/btreelevelcount.en.md

@ -14,7 +14,7 @@ func BTreeLevelCount(root *TreeNode) int {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/btreelevelcount.fr.md

@ -14,7 +14,7 @@ func BTreeLevelCount(root *TreeNode) int {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/btreemax.en.md

@ -14,7 +14,7 @@ func BTreeMax(root *TreeNode) *TreeNode {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/btreemax.fr.md

@ -14,7 +14,7 @@ func BTreeMax(root *TreeNode) *TreeNode {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/btreemin.en.md

@ -14,7 +14,7 @@ func BTreeMin(root *TreeNode) *TreeNode {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/btreemin.fr.md

@ -14,7 +14,7 @@ func BTreeMin(root *TreeNode) *TreeNode {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/btreeprintroot.en.md

@ -20,7 +20,7 @@ func PrintRoot(root *TreeNode){
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/btreeprintroot.fr.md

@ -20,7 +20,7 @@ func PrintRoot(root *TreeNode){
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/btreesearchitem.en.md

@ -14,7 +14,7 @@ func BTreeSearchItem(root *TreeNode, elem string) *TreeNode {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/btreesearchitem.fr.md

@ -14,7 +14,7 @@ func BTreeSearchItem(root *TreeNode, elem string) *TreeNode {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/btreetransplant.en.md

@ -14,7 +14,7 @@ func BTreeTransplant(root, node, rplc *TreeNode) *TreeNode {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/btreetransplant.fr.md

@ -14,7 +14,7 @@ func BTreeTransplant(root, node, rplc *TreeNode) *TreeNode {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/capitalize.en.md

@ -16,7 +16,7 @@ func Capitalize(s string) string {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/capitalize.fr.md

@ -16,7 +16,7 @@ func Capitalize(s string) string {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

4
subjects/changeorder.en.md

@ -68,7 +68,7 @@ func main() {
Its output:
```console
$> go build
$> ./main
$ go build
$ ./main
1 -> 3 -> 5 -> 2 -> 4
```

55
subjects/chunk.en.md

@ -0,0 +1,55 @@
## chunk
## **WARNING! VERY IMPORTANT!**
For this exercise a function will be tested **with the exam own main**. However the student **still needs** to submit a structured program:
This means that:
- The package needs to be named `package main`.
- The submitted code needs one declared function main(```func main()```) even if empty.
- The function main declared needs to **also pass** the `Restrictions Checker`(illegal functions tester). It is advised for the student to just empty the function main after its own testings are done.
- Every other rules are obviously the same than for a `program`.
### Instructions
Write a function called `Chunk` that receives as parameters a slice, `slice []int`, and an number `size int`. The goal of this function is to chunk a slice into many sub slices where each sub slice has the length of `size`.
- If the `size` is `0` it should print `\n`
### Expected function
```go
func Chunk(slice []int, size int) {
}
```
### Usage
Here is a possible program to test your function :
```go
package main
func main() {
Chunk([]int{}, 10)
Chunk([]int{0, 1, 2, 3, 4, 5, 6, 7}, 0)
Chunk([]int{0, 1, 2, 3, 4, 5, 6, 7}, 3)
Chunk([]int{0, 1, 2, 3, 4, 5, 6, 7}, 5)
Chunk([]int{0, 1, 2, 3, 4, 5, 6, 7}, 4)
}
```
And its output :
```console
student@ubuntu:~/[[ROOT]]/test$ go build
student@ubuntu:~/[[ROOT]]/test$ ./test
[]
[[0 1 2] [3 4 5] [6 7]]
[[0 1 2 3 4] [5 6 7]]
[[0 1 2 3] [4 5 6 7]]
student@ubuntu:~/[[ROOT]]/test$
```

2
subjects/cl.en.md

@ -12,7 +12,7 @@ Put in a file `mastertheLS` the command line that will:
- list the files and folders of the current folder.
- Ignore the hidden files, the "." and the "..".
- Separates the resuls with commas.
- Separates the results with commas.
- Order them by ascending order of creation date.
- Have the folders have a `/` in front of them.

2
subjects/cl.fr.md

@ -12,7 +12,7 @@ Put in a file `mastertheLS` the command line that will:
- list the files and folders of the current folder.
- Ignore the hidden files, the "." and the "..".
- Separates the resuls with commas.
- Separates the results with commas.
- Order them by ascending order of creation date.
- Have the folders have a `/` in front of them.

1
subjects/cleanstr.en.md

@ -3,6 +3,7 @@
### Instructions
Write a **program** that takes a `string`, and displays this `string` with exactly:
- one space between words.
- without spaces nor tabs at the beginning nor at the end.
- with the result followed by a newline ("`\n`").

1
subjects/cleanstr.fr.md

@ -3,6 +3,7 @@
### Instructions
Écrire un programme qui prend une `string`, et qui affiche cette `string` avec exactement:
- un espace entre les mots.
- aucun espace ni de tabulation ni au début ni à la fin.
- le résultat avecsuivi d'un saut de ligne("`\n`").

2
subjects/collatzcountdown.en.md

@ -16,7 +16,7 @@ func CollatzCountdown(start int) int {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/collatzcountdown.fr.md

@ -16,7 +16,7 @@ func CollatzCountdown(start int) int {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/compact.en.md

@ -19,7 +19,7 @@ func Compact(ptr *[]string) int {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/compact.fr.md

@ -19,7 +19,7 @@ func Compact(ptr *[]string) int {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/compare.en.md

@ -14,7 +14,7 @@ func Compare(a, b string) int {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/compare.fr.md

@ -14,7 +14,7 @@ func Compare(a, b string) int {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/compareprog.en.md

@ -6,7 +6,7 @@ Write a program that behaves like the `Compare` function from the `Go` package `
This program prints a number after comparing two `string` lexicographically.
### Usage :
### Usage
```console
student@ubuntu:~/compareprog$ go build

2
subjects/concat.en.md

@ -14,7 +14,7 @@ func Concat(str1 string, str2 string) string {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/concat.fr.md

@ -14,7 +14,7 @@ func Concat(str1 string, str2 string) string {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/concatparams.en.md

@ -16,7 +16,7 @@ func ConcatParams(args []string) string {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/concatparams.fr.md

@ -16,7 +16,7 @@ func ConcatParams(args []string) string {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/convertbase.en.md

@ -18,7 +18,7 @@ func ConvertBase(nbr, baseFrom, baseTo string) string {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/convertbase.fr.md

@ -18,7 +18,7 @@ func ConvertBase(nbr, baseFrom, baseTo string) string {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

24
subjects/costumeprofit.en.md

@ -0,0 +1,24 @@
## costumeprofit
### Instructions
Shop is selling **a** ties, **b** scarfs, **c** waistcoats, **d** jackets.
- You want to make a costume. There are 2 types of costumes :
- 1 - costume composed of tie and jacket.
- 2 - costume composed of scarf, waistcoat, and jacket.
Costumes of first type cost **e** dollars, of second type cost **f** dollars.
What is the maximum amount of dollars that shop can earn by selling costumes?
Input will be given as 6 arguments, your output should be displayed as standard output.
In the output put '\n' at the end.
Input: `./main **a** **b** **c** **d** **e** **f**`
```console
$> ./main 12 11 13 20 4 6
102
```

2
subjects/countif.en.md

@ -14,7 +14,7 @@ func CountIf(f func(string) bool, tab []string) int {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/countif.fr.md

@ -14,7 +14,7 @@ func CountIf(f func(string) bool, tab []string) int {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/createelem.en.md

@ -18,7 +18,7 @@ func CreateElem(n *Node, value int) {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/createelem.fr.md

@ -18,7 +18,7 @@ func CreateElem(n *Node, value int) {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

2
subjects/divmod.en.md

@ -18,7 +18,7 @@ func DivMod(a int, b int, div *int, mod *int) {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/divmod.fr.md

@ -18,7 +18,7 @@ func DivMod(a int, b int, div *int, mod *int) {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

47
subjects/doppelgangerprog.en.md

@ -0,0 +1,47 @@
## doppelganger
## **WARNING! VERY IMPORTANT!**
For this exercise a function will be tested **with the exam own main**. However the student **still needs** to submit a structured program:
This means that:
- The package needs to be named `package main`.
- The submitted code needs one declared function main(```func main()```) even if empty.
- The function main declared needs to **also pass** the `Restrictions Checker`(illegal functions tester). It is advised for the student to just empty the function main after its own testings are done.
- Every other rules are obviously the same than for a `program`.
### Instructions
You are given 2 strings. Find out if first string contains second string. If it does, return index of the first string where second string occurs last time. If it does not contain, return "-1"
### Expected function
```go
package main
func DoppelGanger(big, little string) int {
}
```
```go
package main
import (
"fmt"
)
func main() {
var result int
result = DoppelGanger("aaaaaaa", "a")
fmt.Println(result) // 6
result = DoppelGanger("qwerty", "t")
fmt.Println(result) // 4
result = DoppelGanger("a", "b")
fmt.Println(result) // -1
}
```

2
subjects/enigma.en.md

@ -21,7 +21,7 @@ func Enigma(a ***int, b *int, c *******int, d ****int) {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

2
subjects/enigma.fr.md

@ -20,7 +20,7 @@ func Enigma(a ***int, b *int, c *******int, d ****int) {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main

60
subjects/fib.en.md

@ -0,0 +1,60 @@
## fib
## **WARNING! VERY IMPORTANT!**
For this exercise a function will be tested **with the exam own main**. However the student **still needs** to submit a structured program:
This means that:
- The package needs to be named `package main`.
- The submitted code needs one declared function main(```func main()```) even if empty.
- The function main declared needs to **also pass** the `Restrictions Checker`(illegal functions tester). It is advised for the student to just empty the function main after its own testings are done.
- Every other rules are obviously the same than for a `program`.
### Instructions
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32.
The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham.
You are given a non-negative integer n, please find nth element of fibonacci sequence.
Fib(0) = 0,
Fib(1) = 1, otherwise, nth element is the sum of the 2 previous elements of the series.
### Expected function
```go
func Fib(n int) int {
}
```
### Usage
Here is a possible program to test your function :
```go
package main
import (
"fmt"
)
func main() {
fmt.Println(Fib(0))
fmt.Println(Fib(1))
fmt.Println(Fib(2))
}
```
And its output :
```console
student@ubuntu:~/[[ROOT]]/test$ go build
student@ubuntu:~/[[ROOT]]/test$ ./test
0
1
1
student@ubuntu:~/[[ROOT]]/test$
```

6
subjects/fibonacci.en.md

@ -24,14 +24,14 @@ func Fibonacci(index int) int {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main
import (
        "fmt"
        piscine ".."
"fmt"
piscine ".."
)
func main() {

4
subjects/fibonacci.fr.md

@ -30,8 +30,8 @@ Voici un éventuel `main.go` :
package main
import (
        "fmt"
        piscine ".."
"fmt"
piscine ".."
)
func main() {

2
subjects/findnextprime.en.md

@ -16,7 +16,7 @@ func FindNextPrime(nb int) int {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

6
subjects/findnextprime.fr.md

@ -16,14 +16,14 @@ func FindNextPrime(nb int) int {
### Utilisation
Voici un éventuel [programme](TODO-LINK) pour tester votre fonction :
Voici un éventuel programme pour tester votre fonction :
```go
package main
import (
        "fmt"
        piscine ".."
"fmt"
piscine ".."
)
func main() {

53
subjects/findprevprimeprog.en.md

@ -0,0 +1,53 @@
## findprevprime
## **WARNING! VERY IMPORTANT!**
For this exercise a function will be tested **with the exam own main**. However the student **still needs** to submit a structured program:
This means that:
- The package needs to be named `package main`.
- The submitted code needs one declared function main(\`\`\`func main()\`\`\`) even if empty.
- The function main declared needs to **also pass** the \`Restrictions Checker\`(illegal functions tester). It is advised for the student to just empty the function main after its own testings are done.
- Every other rules are obviously the same than for a \`program\`.
### Instructions
Write a function that returns the first prime number that is equal or inferior to the `int` passed as parameter.
If there are no primes inferior to the `int` passed as parameter the function should return 0.
### Expected function
```go
func FindPrevPrime(nb int) int {
}
```
### Usage
Here is a possible [program](TODO-LINK) to test your function :
```go
package main
import (
"fmt"
)
func main() {
fmt.Println(FindPrevPrime(5))
fmt.Println(FindPrevPrime(4))
}
```
And its output :
```console
student@ubuntu:~/piscine-go/test$ go build
student@ubuntu:~/piscine-go/test$ ./test
5
3
student@ubuntu:~/piscine-go/test$
```

2
subjects/firstrune.en.md

@ -14,7 +14,7 @@ func FirstRune(s string) rune {
### Usage
Here is a possible [program](TODO-LINK) to test your function :
Here is a possible program to test your function :
```go
package main

Some files were not shown because too many files changed in this diff diff.show_more

Loading…
Cancel
Save