Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Building a training set of tags for cfml #184

Closed
ErikSchierboom opened this issue Oct 31, 2023 · 21 comments
Closed

Building a training set of tags for cfml #184

ErikSchierboom opened this issue Oct 31, 2023 · 21 comments

Comments

@ErikSchierboom
Copy link
Member

Hello lovely maintainers 👋

We've recently added "tags" to student's solutions. These express the constructs, paradigms and techniques that a solution uses. We are going to be using these tags for lots of things including filtering, pointing a student to alternative approaches, and much more.

In order to do this, we've built out a full AST-based tagger in C#, which has allowed us to do things like detect recursion or bit shifting. We've set things up so other tracks can do the same for their languages, but its a lot of work, and we've determined that actually it may be unnecessary. Instead we think that we can use machine learning to achieve tagging with good enough results. We've fine-tuned a model that can determine the correct tags for C# from the examples with a high success rate. It's also doing reasonably well in an untrained state for other languages. We think that with only a few examples per language, we can potentially get some quite good results, and that we can then refine things further as we go.

I released a new video on the Insiders page that talks through this in more detail.

We're going to be adding a fully-fledged UI in the coming weeks that allow maintainers and mentors to tag solutions and create training sets for the neural networks, but to start with, we're hoping you would be willing to manually tag 20 solutions for this track. In this post we'll add 20 comments, each with a student's solution, and the tags our model has generated. Your mission (should you choose to accept it) is to edit the tags on each issue, removing any incorrect ones, and add any that are missing. In order to build one model that performs well across languages, it's best if you stick as closely as possible to the C# tags as you can. Those are listed here. If you want to add extra tags, that's totally fine, but please don't arbitrarily reword existing tags, even if you don't like what Erik's chosen, as it'll just make it less likely that your language gets the correct tags assigned by the neural network.


To summarise - there are two paths forward for this issue:

  1. You're up for helping: Add a comment saying you're up for helping. Update the tags some time in the next few days. Add a comment when you're done. We'll then add them to our training set and move forward.
  2. You not up for helping: No problem! Just please add a comment letting us know :)

If you tell us you're not able/wanting to help or there's no comment added, we'll automatically crowd-source this in a week or so.

Finally, if you have questions or want to discuss things, it would be best done on the forum, so the knowledge can be shared across all maintainers in all tracks.

Thanks for your help! 💙


Note: Meta discussion on the forum

@ErikSchierboom
Copy link
Member Author

Exercise: raindrops

Code

component {
	/**
	* @returns
	*/
	public string function convert( required numeric number ){
		var output = "";
		if( number % 3 == 0 ){
			output = output & "Pling";
		}
		if( number % 5 == 0 ){
			output = output & "Plang";
		}
		if( number % 7 == 0 ){
			output = output & "Plong";
		}
		if( number % 3 != 0 && number % 5 != 0 && number % 7 != 0){
			output = output & number.toString();
		}
		return output;
	}
}

Tags:

construct:assignment
construct:bitwise-and
construct:boolean
construct:comment
construct:component
construct:if
construct:logical-and
construct:method
construct:number
construct:parameter
construct:return
construct:string
construct:var
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:boolean-logic
technique:bit-manipulation

@ErikSchierboom
Copy link
Member Author

Exercise: difference-of-squares

Code

/**
* Your implmentation of the DifferenceOfSquares exercise
*/
component {
	
	 function squareOfSum( number ) {
		var number = 0;
		var sum = 0;
		var result = 0;
    for(i=1; i<=10; i++) {
		number = number + 1;
		sum = sum + number;
		result = sum;
	}
	square = result * result;
		return square;
	}
	
	 function sumOfSquares( number ) {
		var number = [1];
		var result = 0;
		for(i=1; i<10; i++) {
			var sq = number * number;
			result = result + sq;
			number = arrayAppend(number, number+1);
		}
		return result;
	}
	
	 function differenceOfSquares( number ) {
		var number = square - result;
		return number;
	}
	
}

Tags:

construct:add
construct:assignment
construct:comment
construct:component
construct:for-loop
construct:function
construct:invocation
construct:method
construct:number
construct:parameter
construct:return
construct:subtract
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:looping

@ErikSchierboom
Copy link
Member Author

Exercise: secret-handshake

Code

/**
* Your implmentation of the SecretHandshake exercise
*/
component {
	
	/**
	* @returns 
	*/

	function commands( number ) {
		ans = [];
		if (int(number)%2==1) arrayAppend(ans, 'wink');
		if (int(number/2)%2==1) arrayAppend(ans, 'double blink');
		if (int(number/4)%2==1) arrayAppend(ans, 'close your eyes');
		if (int(number/8)%2==1) arrayAppend(ans, 'jump');
		if (int(number/16)%2==1) {
			temp = duplicate(ans);
			for (i=1;i<=len(ans);i++) {
				ans[i] = temp[len(temp)+1-i];
			}
		}
		return ans;
	}
	
}

Tags:

construct:add
construct:assignment
construct:comment
construct:component
construct:divide
construct:for-loop
construct:function
construct:if
construct:index
construct:int
construct:integral-number
construct:invocation
construct:method
construct:number
construct:parameter
construct:return
construct:string
construct:subtract
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:looping

@ErikSchierboom
Copy link
Member Author

Exercise: space-age

Code

/**
* Your implmentation of the SpaceAge exercise
*/
component {
	
	/**
	* @planet planet we want to know the age on
	* @seconds seconds of lifetime
	* @returns age in years based on @planet and @seconds
	*/
	public numeric function age( required string planet, required numeric seconds ) {
		 var earthAge = arguments.seconds / 31557600;
		 var coef = 1;
		 switch (lCase(arguments.planet)) {
			 case "mercury":
				 coef = 0.2408467;
				 break;
			 case "venus":
				 coef = 0.61519726;
				 break;
			 case "mars":
				 coef = 1.8808158;
				 break;
			 case "jupiter":
				 coef = 11.862615;
				 break;
			 case "saturn":
				 coef = 29.447498;
				 break;
			 case "uranus":
				 coef = 84.016846;
				 break;
			 case "neptune":
				 coef = 164.79132;
				 break;
			 default:
		 }

		 return numberFormat(earthAge / coef, "9.99");
	}
	
}

Tags:

construct:assignment
construct:break
construct:comment
construct:component
construct:divide
construct:implicit-conversion
construct:invocation
construct:method
construct:number
construct:parameter
construct:return
construct:string
construct:switch
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented

@ErikSchierboom
Copy link
Member Author

Exercise: space-age

Code

component{
	/**
	* @returns
	*/
	public numeric function age( required string planet, required numeric seconds ) {
		var secondsInYearEarth = 31557600
		var planetaryValues = {
			"Earth" : secondsInYearEarth,
			"Mercury" : 0.2408467 * secondsInYearEarth,
			"Venus" : 0.61519726 * secondsInYearEarth,
			"Mars" : 1.8808158 * secondsInYearEarth,
			"Jupiter" : 11.862615 * secondsInYearEarth,
			"Saturn" : 29.447498 * secondsInYearEarth,
			"Uranus" : 84.016846 * secondsInYearEarth,
			"Neptune" : 164.79132 * secondsInYearEarth
		}
		if(structKeyExists(planetaryValues, planet)){
			var age = numberFormat(seconds / planetaryValues[planet], "0.00");
		}
		return age;
	}
}

Tags:

construct:divide
construct:if
construct:invocation
construct:method
construct:number
construct:parameter
construct:return
construct:string
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented

@ErikSchierboom
Copy link
Member Author

Exercise: space-age

Code

/**
* Your implmentation of the SpaceAge exercise
*/
component {
	
	/**
	* @returns 
	*/
	 function age( planet, seconds ) {
		var secsInEarthYear = 31557600;
		var answer = ""
		switch( planet ) {
			case "Earth":
				answer = seconds / secsInEarthYear;
				break;
			case "Mercury":
				answer = seconds / (0.2408467 * secsInEarthYear);
				break;
			case "Venus":
				answer = seconds / (0.61519726 * secsInEarthYear);
				break;
			case "Mars":
				answer = seconds/ (1.8808158 * secsInEarthYear);
				break;
			case "Jupiter":
				answer = seconds / (11.862615 * secsInEarthYear);
				break;
			case "Saturn":
				answer = seconds / (29.447498 * secsInEarthYear);
				break;
			case "Uranus":
				answer = seconds / (84.016846 * secsInEarthYear);
				break;
			case "Neptune":
				answer = seconds / (164.79132 * secsInEarthYear);
				break;
			default:
				return -1
				break;
			}
			return round(answer, 2);
		}
}

Tags:

construct:assignment
construct:break
construct:comment
construct:component
construct:divide
construct:floating-point-number
construct:function
construct:implicit-conversion
construct:integral-number
construct:invocation
construct:number
construct:parameter
construct:return
construct:switch
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented

@ErikSchierboom
Copy link
Member Author

Exercise: rna-transcription

Code

component {
	/**
	* @returns
	*/
	public string function toRNA( required string DNA ) {
		var converterTable = {
			"G" = "C",
			"C" = "G",
			"T" = "A",
			"A" = "U"
		};
		var splitStrand = DNA.split("");
		var RNA = "";
		for(var strand in splitStrand){
			if(structKeyExists(converterTable, strand)){
				strand = converterTable[strand];
				RNA = RNA & strand;
			}
		}
		return RNA;
	}
}

Tags:

construct:assignment
construct:bitwise-and
construct:cfml
construct:class
construct:comment
construct:component
construct:for-loop
construct:if
construct:indexed-access
construct:initializer
construct:invocation
construct:method
construct:object
construct:parameter
construct:return
construct:string
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:bit-manipulation
technique:looping

@ErikSchierboom
Copy link
Member Author

Exercise: rna-transcription

Code

/**
* Your implmentation of the RnaTranscription exercise
*/
component {
	
	/**
	* @returns 
	*/
	 function toRNA( DNA ) {
		conv = {'G':'C','C':'G','T':'A','A':'U'};
		ans = ''
		for (letter in listToArray(DNA,'')) {
			ans &= conv[letter];
		}
		return ans;
	}
	
}

Tags:

No tags generated

@ErikSchierboom
Copy link
Member Author

Exercise: hamming

Code

component {
	/**
	* @returns 
	*/
	public numeric function distance( required string strand1, required string strand2 ) {
		var hammingDistance = 0;
		if( len(strand1) == len(strand2) ){
			strand1 = strand1.split("");
			strand2 = strand2.split("");
			for( var i=1; i<=arrayLen(strand1); i++){
				if( strand1[i] != strand2[i] ){
					hammingDistance += 1; 
				}
			}
			return hammingDistance;
		}throw("left and right strands must be of equal length")
	}
}

Tags:

construct:assignment
construct:array
construct:comment
construct:component
construct:for-loop
construct:if
construct:indexing
construct:integral-number
construct:invocation
construct:len
construct:method
construct:number
construct:parameter
construct:return
construct:string
construct:throw
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:exceptions
technique:looping

@ErikSchierboom
Copy link
Member Author

Exercise: hamming

Code

component {
	
	public numeric function distance( required string strand1, required string strand2 ) {

		var array1 = listToArray(arguments.strand1, "");
		var array2 = listToArray(arguments.strand2, "");
		var hammingDistance = 0;
		if (ArrayLen(array1) != ArrayLen(array2)) {
			throw("left and right strands must be of equal length")
		}
		for (var i = 1; i <= len(array1); i++) {
			if (array1[i] != array2[i]) {
				hammingDistance += 1;
			}
		}
		return hammingDistance;
	}
}

Tags:

construct:assignment
construct:component
construct:for-loop
construct:if
construct:index
construct:invocation
construct:list
construct:number
construct:parameter
construct:return
construct:string
construct:throw
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:exceptions
technique:looping

@ErikSchierboom
Copy link
Member Author

Exercise: gigasecond

Code

component {
	/**
	* @returns
	*/
	public date function add( required date birthdate ) {
		return dateAdd('s' , 10^9, birthdate);
	}
}

Tags:

cfml
construct:caret
construct:component
construct:date
construct:dateadd
construct:documentation
construct:double
construct:exponentiation
construct:float
construct:function
construct:implicit-conversion
construct:invocation
construct:number
construct:parameter
construct:return
construct:string
construct:visibility-modifiers
paradigm:functional
paradigm:object-oriented
technique:math

@ErikSchierboom
Copy link
Member Author

Exercise: sum-of-multiples

Code

/**
* Your implmentation of the SumOfMultiples exercise
*/
component {
	
	/**
	* @returns 
	*/
	function sum( array factors, limit ) {
		var uniques = [];
		var multiple = 0;
		// add the multiples of the factors less than the limit
		// and add them to the unique list.
		// loop through each item in factors array
		for(var i = 1; i <= factors.len();i++){
			// lets get the multiples of each factor 
			for(var j = 1; j <= limit; j++){
				multiple = j*factors[i];
				if(not uniques.contains(multiple) and multiple lt limit){
					uniques.append(multiple);
				}
			}
		}
		return uniques.sum();
	}
	
}

Tags:

No tags generated

@ErikSchierboom
Copy link
Member Author

Exercise: luhn

Code

/**
* Your implmentation of the Luhn exercise
*/
component {
	
	/**
	* @returns 
	*/
	function valid( value ) {
		// two test fail
		// implmentation http://taggedwiki.zubiaga.org/new_content/c5837348dbddc2483f3fe40ffb62b46d
		_sum=0;
		alt=False;
		values=arrayReverse(value.split(''));
		if (arrayLen(values)==1) {
			return false;
		}
		for (d in values) {
			if (isNumeric(d)){
				d=LSParseNumber(d);
			}else{
				return false;
			}
			if (0>=d && d>=9){
				return false;
			}
			if (alt){
				d *=2;
				if (d>9){
					d-=9;
				}
			}
			_sum+=d;
			alt=!alt;
		}
		return (_sum%10) == 0;
	}
}

Tags:

construct:assignment
construct:boolean
construct:comment
construct:component
construct:constructor
construct:for-loop
construct:function
construct:if
construct:implicit-conversion
construct:invocation
construct:logical-and
construct:method
construct:number
construct:parameter
construct:return
construct:string
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:boolean-logic
technique:looping

@ErikSchierboom
Copy link
Member Author

Exercise: luhn

Code

/**
* Your implmentation of the Luhn exercise
*/
component {
	
	/**
	* @returns 
	*/
	function valid( value ) {
		// remove spaces
		value = replace(value, " ", "", "ALL");
		// is it valid?
		if(len(value) eq 1) return false;
		if(not isNumeric(value)) return false;

		var doubled = [];		
		var digits = listToArray(lsParseNumber(value),""); // [5,9]
		for(var i = digits.len(); i >= 1; i--){
			var curDigit = toNumeric(digits[i]);
			if(i % 2 neq 1){
				arrayAppend(doubled, curDigit);
			}else{
				if( digits[i]*2 gt 9){
					arrayAppend(doubled, curDigit*2-9);
				}else{
					arrayAppend(doubled, curDigit*2);
				}
			}
		}
		if(doubled.sum() % 10 eq 0 ){
			return true;
		}else{
			return false;
		}

	}
	
}

Tags:

construct:assignment
construct:boolean
construct:comment
construct:component
construct:for-loop
construct:function
construct:if
construct:implicit-conversion
construct:index
construct:invocation
construct:lambda
construct:list
construct:method
construct:multiply
construct:number
construct:parameter
construct:return
construct:string
construct:subtract
construct:tag
construct:varargs
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:higher-order-functions
technique:looping
uses:List

@ErikSchierboom
Copy link
Member Author

Exercise: largest-series-product

Code

/**
* Your implmentation of the LargestSeriesProduct exercise
*/
component {
	
	/**
	* @returns 
	*/
	function largestProduct( digits, span ) {

		if ((len(digits)<lsParseNumber(span))||(lsParseNumber(span)<0)) {
			return -1;
		}
		if (lsParseNumber(span)==0) {
			return 1;
		}
		max=0;
		for (i = 1; i < len(digits); i++) {
			if (!i+lsParseNumber(span)>len(digits)+1) {
				sub=mid(digits,i,span).split('');
				tmp=1;
				for (j = 1; j < arrayLen(sub)+1; j++) {
					if (!isNumeric(sub[j])) {
						return -1;
					}
					tmp*=lsParseNumber(sub[j]);
				}
				if (max<tmp) {
					max=tmp;
				}

			}

		}
		return max;
	}
	
}

Tags:

construct:add
construct:assignment
construct:boolean
construct:comment
construct:component
construct:for-loop
construct:function
construct:if
construct:index
construct:invocation
construct:logical-or
construct:number
construct:parameter
construct:return
construct:string
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:boolean-logic
technique:looping

@ErikSchierboom
Copy link
Member Author

Exercise: nth-prime

Code

/**
* Your implmentation of the NthPrime exercise
*/
component {

	/**
	* @returns
	*/
	function prime( number ) {
		if (lsParseNumber(number)==0) {
			throw('there is no zeroth prime' );
		}
		ctr=0;
		dvr=2;
		while (ctr<lsParseNumber(number)) {
			if (isPrime(dvr)) {
				ctr+=1;
			}
			dvr+=1;
		}
		return dvr-=1;
	}

	function isPrime( number ) {
		for (i = 2; i < number; i++) {
			if (number%i==0){
				return false;
			}
		}
		return true;
	}

}

Tags:

construct:assignment
construct:boolean
construct:comment
construct:component
construct:constructor
construct:for-loop
construct:function
construct:if
construct:implicit-conversion
construct:invocation
construct:method
construct:number
construct:parameter
construct:return
construct:string
construct:subtract
construct:throw
construct:variable
construct:visibility-modifiers
construct:while-loop
paradigm:imperative
paradigm:object-oriented
technique:exceptions
technique:looping

@ErikSchierboom
Copy link
Member Author

Exercise: diamond

Code

component {
	/**
	* @returns
	*/
	public string function generateSpaces( required numeric number ){
		var spaceString = "";
		for( var i = 1; i <= number; i++ ){
			spaceString = spaceString & " ";
		}
		return spaceString;
	}
	public array function rows( required string letter ) {
		var values = {
			"A" = 1,
			"B" = 2,
			"C" = 3,
			"D" = 4,
			"E" = 5,
			"F" = 6,
			"G" = 7,
			"H" = 8,
			"I" = 9,
			"J" = 10,
			"K" = 11,
			"L" = 12,
			"M" = 13,
			"N" = 14,
			"O" = 15,
			"P" = 16,
			"Q" = 17,
			"R" = 18,
			"S" = 19,
			"T" = 20,
			"U" = 21,
			"V" = 22,
			"W" = 23,
			"X" = 24,
			"Y" = 25,
			"Z" = 26
		};
		var firstHalf = [];
		var secondHalf = [];
		var output = [];
		var center = 1;
		for( var i = 1; i <= values[letter]; i++){
			var alpha = structFindValue(values, i, "one")[1].key;
			var leftRight = values[letter] - i;
			if( i == 1 ){
				arrayAppend(firstHalf, generateSpaces( leftRight ) & alpha & generateSpaces( leftRight  ) );
			}
			else{
				arrayAppend(firstHalf, generateSpaces( leftRight  ) & alpha & generateSpaces(center) & alpha & generateSpaces( leftRight  ) );
				center += 2;
			}

		}
		for( var i = arrayLen(firstHalf) - 1; i >= 1; i--){
			arrayAppend(secondHalf, firstHalf[i]);
		}
		for( var i = 1; i <= arrayLen(firstHalf); i++){
			arrayAppend(output, firstHalf[i] );
		}
		for( var i = 1; i <= arrayLen(secondHalf); i++){
			arrayAppend(output, secondHalf[i]);
		}
		return output;
	}
}

Tags:

construct:assignment
construct:bitwise-and
construct:for-loop
construct:if
construct:indexing
construct:initializer
construct:integer
construct:invocation
construct:method
construct:number
construct:object
construct:parameter
construct:return
construct:string
construct:subtract
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:bit-manipulation
technique:looping

@ErikSchierboom
Copy link
Member Author

Exercise: bob

Code

/**
* Your implmentation of the Bob exercise
*/
component {

	/**
	* @returns
	*/
	//talking forcefully failed
	function response( heyBob ) {
		tempLL=arrayLen(heyBob.split(' '));
		regLL=len(reFind("[A-Z\^s]",heyBob));
		if ((isEmpty(heyBob))||(len(reReplace(heyBob,"[\t\s\r]+",''))==0)){
			return "Fine. Be that way!";
		}else if ((right(replace(heyBob," ","","ALL"),1)=="?")&&(tempLL<=len(rereplace(heyBob,"[A-Z?]",'',"ALL")))){
			return "Sure.";
		}else if ((right(replace(heyBob," ","","ALL"),1)=="?")&&(tempLL==len(rereplace(heyBob,"[A-Z]",'',"ALL")))){
			return "Calm down, I know what I'm doing!";
		}else if ((right(replace(heyBob," ","","ALL"),1)=="!")||(tempLL>=len(rereplace(heyBob,"[A-Z!]",'',"ALL")))){
			return "Whoa, chill out!";
		}else{
			return "Whatever.";
		}

	}

}

Tags:

construct:array
construct:boolean
construct:char
construct:class
construct:comment
construct:component
construct:constructor
construct:function
construct:if
construct:invocation
construct:logical-or
construct:method
construct:number
construct:parameter
construct:return
construct:string
construct:tempvar
construct:visibility-modifiers
paradigm:object-oriented
technique:boolean-logic

@ErikSchierboom
Copy link
Member Author

Exercise: word-count

Code

component {
	/**
	* @returns
	*/
	public struct function countwords( required string sentence ) {
		wordStruct = {};
		sentence = reReplace(sentence, "[^0-9A-Za-z' ]", "", "all");
		sentence = sentence.split(" ");
		for( word in sentence ){
			if( word != "" ){
				var quote = "'";
				if(word[1] == quote && word[len(quote)] == quote){
					word = replace(word, quote, "", "all");
				}
				if( !structKeyExists( wordStruct, word ) ){
					wordStruct[word] = 1;
				}else{
					wordStruct[word] += 1;
				}
			}
		}
		return wordStruct;
	}
}

Tags:

construct:assignment
construct:boolean
construct:comment
construct:component
construct:for-loop
construct:if
construct:index
construct:method
construct:number
construct:parameter
construct:return
construct:string
construct:struct
construct:struct-key-access
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:looping

@ErikSchierboom
Copy link
Member Author

Exercise: anagram

Code

/**
* Your implmentation of the Anagram exercise
*/
component {

  /**
	* @word word we want the map of
	* @returns a map with all letters of the @word and for each letter, the count
	*/
  private struct function mapWord(required string word) {
    var wordMap = {};
    for (var letter in listToArray(arguments.word, "")) {
      if (structKeyExists(wordMap, letter)) {
        wordMap[letter] += 1;
      } else {
        wordMap[letter] = 1;
      }
    }
    return wordMap;
  }

  /**
	* @subject word we're looking if the @candidate is an anagrams of
	* @candidate candidate of anagram of the @subject
	* @returns true if @candidate is an anagram of @subject
	*/
  private boolean function isAnagram(required string subject, required string candidate) {
    if (lCase(arguments.subject) == lCase(arguments.candidate)) {
      return false;
    }
    var subjectMap = mapWord(arguments.subject);
    var candidateMap = mapWord(arguments.candidate);
    for (var key in candidateMap) {
      if (!structKeyExists(subjectMap, key)) {
        return false;
      }
      if (subjectMap[key] != candidateMap[key]) {
        return false;
      }
    }
		return true;
	}

  /**
	* @subject word we're looking the anagrams of
	* @candidates an array of candidates of anagrams of the @subject
	* @returns an array of anagrams of one word from an array of candidates
	*/
  public array function anagrams(required string subject, required array candidates) {
    var arrayOfAnagrams = [];
    for (var candidate in arguments.candidates) {
      if (isAnagram(arguments.subject, candidate)) {
        arrayOfAnagrams.append(candidate);
      }
    }
    return arrayOfAnagrams;
  }
}

Tags:

construct:assignment
construct:boolean
construct:component
construct:constructor
construct:for-loop
construct:if
construct:index-operator
construct:invocation
construct:list
construct:method
construct:number
construct:parameter
construct:private
construct:return
construct:string
construct:struct
construct:struct-key-exists
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:looping

@ErikSchierboom
Copy link
Member Author

This is an automated comment

Hello 👋 Next week we're going to start using the tagging work people are doing on these. If you've already completed the work, thank you! If you've not, but intend to this week, that's great! If you're not going to get round to doing it, and you've not yet posted a comment letting us know, could you please do so, so that we can find other people to do it. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant